aboutsummaryrefslogtreecommitdiffstats
path: root/syz-cluster
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2025-09-18 17:36:53 +0200
committerTaras Madan <tarasmadan@google.com>2025-10-07 15:25:13 +0000
commit99ed12e158687b7aba55eac142d6bad3f147d029 (patch)
treea9809d7c5d60f45b805e0346a9a543ba0651a9e1 /syz-cluster
parent790f0ffe2224829b20e4dc6556c090c503e1d161 (diff)
syz-cluster: rewrite fuzz config generation
Instead of a predefined set of manually written syz-manager configs, construct it dynamically from different bits. During triage, select not just one, but all matching fuzzer configurations and then merge them together.
Diffstat (limited to 'syz-cluster')
-rw-r--r--syz-cluster/pkg/api/api.go94
-rw-r--r--syz-cluster/pkg/fuzzconfig/base.cfg (renamed from syz-cluster/workflow/configs/all/base.cfg)5
-rw-r--r--syz-cluster/pkg/fuzzconfig/generate.go188
-rw-r--r--syz-cluster/pkg/fuzzconfig/generate_test.go79
-rw-r--r--syz-cluster/pkg/fuzzconfig/patched.cfg (renamed from syz-cluster/workflow/configs/all/patched.cfg)0
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/mixed/bpf_io_uring.base.cfg90
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/mixed/bpf_io_uring.patched.cfg90
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/bpf.base.cfg73
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/bpf.patched.cfg73
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/default.base.cfg49
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/default.patched.cfg49
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/fs.base.cfg168
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/fs.patched.cfg168
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/io_uring.base.cfg63
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/io_uring.patched.cfg63
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/kvm.base.cfg57
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/kvm.patched.cfg57
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/net.base.cfg118
-rw-r--r--syz-cluster/pkg/fuzzconfig/testdata/singular/net.patched.cfg118
-rw-r--r--syz-cluster/pkg/triage/fuzz_target.go82
-rw-r--r--syz-cluster/pkg/triage/fuzz_target_test.go114
-rw-r--r--syz-cluster/workflow/boot-step/Dockerfile1
-rw-r--r--syz-cluster/workflow/boot-step/main.go7
-rw-r--r--syz-cluster/workflow/configs/bpf/base.cfg30
-rw-r--r--syz-cluster/workflow/configs/bpf/patched.cfg10
-rw-r--r--syz-cluster/workflow/configs/fs/base.cfg52
-rw-r--r--syz-cluster/workflow/configs/fs/patched.cfg10
-rw-r--r--syz-cluster/workflow/configs/io-uring/base.cfg27
-rw-r--r--syz-cluster/workflow/configs/io-uring/patched.cfg10
-rw-r--r--syz-cluster/workflow/configs/kvm/base.cfg34
-rw-r--r--syz-cluster/workflow/configs/kvm/patched.cfg10
-rw-r--r--syz-cluster/workflow/configs/net/base.cfg40
-rw-r--r--syz-cluster/workflow/configs/net/patched.cfg10
-rw-r--r--syz-cluster/workflow/fuzz-step/Dockerfile1
-rw-r--r--syz-cluster/workflow/fuzz-step/main.go114
-rw-r--r--syz-cluster/workflow/fuzz-step/main_test.go20
-rw-r--r--syz-cluster/workflow/triage-step/main.go12
37 files changed, 1801 insertions, 385 deletions
diff --git a/syz-cluster/pkg/api/api.go b/syz-cluster/pkg/api/api.go
index feb06be32..8c107b8f4 100644
--- a/syz-cluster/pkg/api/api.go
+++ b/syz-cluster/pkg/api/api.go
@@ -20,11 +20,20 @@ type FuzzTask struct {
FuzzConfig
}
+const (
+ FocusNet = "net"
+ FocusKVM = "kvm"
+ FocusIoUring = "io_uring"
+ FocusBPF = "bpf"
+ FocusFS = "fs"
+)
+
// FuzzConfig represents a set of parameters passed to the fuzz step.
+// The triage step aggregates multiple KernelFuzzConfig to construct FuzzConfig.
type FuzzConfig struct {
- Track string `json:"track"` // E.g. KASAN.
- Config string `json:"config"` // Refers to workflow/configs/{}.
- CorpusURL string `json:"corpus_url"`
+ Track string `json:"track"` // E.g. KASAN.
+ Focus []string `json:"focus"`
+ CorpusURLs []string `json:"corpus_urls"`
// Don't expect kernel coverage for the patched area.
SkipCoverCheck bool `json:"skip_cover_check"`
// Only report the bugs that match the regexp.
@@ -39,19 +48,24 @@ type Tree struct {
EmailLists []string `json:"email_lists"`
}
+// KernelFuzzConfig is a specific fuzzing assignment.
+// Based on it, the triage step will construct FuzzTasks.
+type KernelFuzzConfig struct {
+ EmailLists []string `json:"email_lists"`
+ Track string `json:"track"` // E.g. KASAN.
+ KernelConfig string `json:"kernel_config"`
+ Focus string `json:"focus"`
+ CorpusURL string `json:"corpus_url"`
+ SkipCoverCheck bool `json:"skip_cover_check"`
+ BugTitleRe string `json:"bug_title_re"`
+}
+
// FuzzTriageTarget is a single record in the list of supported fuzz configs.
type FuzzTriageTarget struct {
EmailLists []string `json:"email_lists"`
Campaigns []*KernelFuzzConfig `json:"campaigns"`
}
-// KernelFuzzConfig is a specific fuzzing assignment.
-// Based on it, the triage step will construct FuzzTasks.
-type KernelFuzzConfig struct {
- KernelConfig string `json:"kernel_config"`
- FuzzConfig
-}
-
type BuildRequest struct {
Arch string `json:"arch"`
TreeName string `json:"tree_name"`
@@ -233,8 +247,8 @@ var DefaultTrees = []*Tree{
const (
netCorpusURL = `https://storage.googleapis.com/syzkaller/corpus/ci-upstream-net-kasan-gce-corpus.db`
bpfCorpusURL = `https://storage.googleapis.com/syzkaller/corpus/ci-upstream-bpf-kasan-gce-corpus.db`
- allCorpusURL = `https://storage.googleapis.com/syzkaller/corpus/ci-upstream-kasan-gce-root-corpus.db`
fsCorpusURL = `https://storage.googleapis.com/syzkaller/corpus/ci2-upstream-fs-corpus.db`
+ allCorpusURL = `https://storage.googleapis.com/syzkaller/corpus/ci-upstream-kasan-gce-root-corpus.db`
)
const kasanTrack = "KASAN"
@@ -245,12 +259,10 @@ var FuzzTargets = []*FuzzTriageTarget{
EmailLists: []string{`kvm@vger.kernel.org`},
Campaigns: []*KernelFuzzConfig{
{
+ Track: kasanTrack,
KernelConfig: `upstream-apparmor-kasan.config`,
- FuzzConfig: FuzzConfig{
- Track: kasanTrack,
- Config: `kvm`,
- CorpusURL: allCorpusURL,
- },
+ Focus: FocusKVM,
+ CorpusURL: allCorpusURL,
},
},
},
@@ -258,12 +270,10 @@ var FuzzTargets = []*FuzzTriageTarget{
EmailLists: []string{`io-uring@vger.kernel.org`},
Campaigns: []*KernelFuzzConfig{
{
+ Track: kasanTrack,
KernelConfig: `upstream-apparmor-kasan.config`,
- FuzzConfig: FuzzConfig{
- Track: kasanTrack,
- Config: `io-uring`,
- CorpusURL: allCorpusURL,
- },
+ Focus: FocusIoUring,
+ CorpusURL: allCorpusURL,
},
},
},
@@ -271,12 +281,10 @@ var FuzzTargets = []*FuzzTriageTarget{
EmailLists: []string{`bpf@vger.kernel.org`},
Campaigns: []*KernelFuzzConfig{
{
+ Track: kasanTrack,
KernelConfig: `upstream-apparmor-kasan.config`,
- FuzzConfig: FuzzConfig{
- Track: kasanTrack,
- Config: `bpf`,
- CorpusURL: bpfCorpusURL,
- },
+ Focus: FocusBPF,
+ CorpusURL: bpfCorpusURL,
},
},
},
@@ -288,12 +296,10 @@ var FuzzTargets = []*FuzzTriageTarget{
},
Campaigns: []*KernelFuzzConfig{
{
+ Track: kasanTrack,
KernelConfig: `upstream-apparmor-kasan.config`,
- FuzzConfig: FuzzConfig{
- Track: kasanTrack,
- Config: `net`,
- CorpusURL: netCorpusURL,
- },
+ Focus: FocusNet,
+ CorpusURL: netCorpusURL,
},
},
},
@@ -307,11 +313,9 @@ var FuzzTargets = []*FuzzTriageTarget{
Campaigns: []*KernelFuzzConfig{
{
KernelConfig: `upstream-apparmor-kasan.config`,
- FuzzConfig: FuzzConfig{
- Track: kasanTrack,
- Config: `fs`,
- CorpusURL: fsCorpusURL,
- },
+ Track: kasanTrack,
+ Focus: FocusFS,
+ CorpusURL: fsCorpusURL,
},
},
},
@@ -320,13 +324,10 @@ var FuzzTargets = []*FuzzTriageTarget{
Campaigns: []*KernelFuzzConfig{
{
KernelConfig: `upstream-apparmor-kasan.config`,
- FuzzConfig: FuzzConfig{
- Track: kasanTrack,
- Config: `all`,
- CorpusURL: allCorpusURL,
- // Not all mm/ code is instrumented with KCOV.
- SkipCoverCheck: true,
- },
+ Track: kasanTrack,
+ CorpusURL: allCorpusURL,
+ // Not all mm/ code is instrumented with KCOV.
+ SkipCoverCheck: true,
},
},
},
@@ -335,11 +336,8 @@ var FuzzTargets = []*FuzzTriageTarget{
Campaigns: []*KernelFuzzConfig{
{
KernelConfig: `upstream-apparmor-kasan.config`,
- FuzzConfig: FuzzConfig{
- Track: kasanTrack,
- Config: `all`,
- CorpusURL: allCorpusURL,
- },
+ Track: kasanTrack,
+ CorpusURL: allCorpusURL,
},
},
},
diff --git a/syz-cluster/workflow/configs/all/base.cfg b/syz-cluster/pkg/fuzzconfig/base.cfg
index 8b98015dd..add1ba131 100644
--- a/syz-cluster/workflow/configs/all/base.cfg
+++ b/syz-cluster/pkg/fuzzconfig/base.cfg
@@ -7,13 +7,10 @@
"syzkaller": "/syzkaller",
"workdir": "/workdir",
"type": "qemu",
-# The perf_event_open call generates too many false positive stalls.
-# The hfs/gfs mounts result in too many distracting kernel crashes that slow down diff fuzzing.
- "disable_syscalls": [ "perf_event_open*", "syz_mount_image$hfs", "syz_mount_image$gfs*"],
"procs": 3,
"sandbox": "none",
"experimental": {"cover_edges": false},
- "vm": {
+ "vm": {
"count": 3,
"cmdline": "root=/dev/sda1",
"kernel": "/base/kernel",
diff --git a/syz-cluster/pkg/fuzzconfig/generate.go b/syz-cluster/pkg/fuzzconfig/generate.go
new file mode 100644
index 000000000..5b503e3ae
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/generate.go
@@ -0,0 +1,188 @@
+// Copyright 2025 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package fuzzconfig
+
+import (
+ _ "embed"
+ "encoding/json"
+ "fmt"
+
+ "github.com/google/syzkaller/pkg/config"
+ "github.com/google/syzkaller/pkg/mgrconfig"
+ "github.com/google/syzkaller/syz-cluster/pkg/api"
+)
+
+//go:embed base.cfg
+var baseConfigJSON []byte
+
+//go:embed patched.cfg
+var patchedConfigJSON []byte
+
+// GenerateBase produces a syz-manager config for the base kernel.
+// The caller must still invoke mgrconfig.Complete.
+func GenerateBase(cfg *api.FuzzConfig) (*mgrconfig.Config, error) {
+ var baseRaw json.RawMessage
+ err := config.LoadData(baseConfigJSON, &baseRaw)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read the base config: %w", err)
+ }
+ base, err := mgrconfig.LoadPartialData(baseRaw)
+ if err != nil {
+ return nil, fmt.Errorf("failed to load the config: %w", err)
+ }
+ err = applyFuzzConfig(base, cfg)
+ if err != nil {
+ return nil, err
+ }
+ return base, nil
+}
+
+// GeneratePatched produces a syz-manager config for the base kernel.
+// The caller must still invoke mgrconfig.Complete.
+func GeneratePatched(cfg *api.FuzzConfig) (*mgrconfig.Config, error) {
+ var baseRaw, deltaRaw json.RawMessage
+ err := config.LoadData(baseConfigJSON, &baseRaw)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read the base config: %w", err)
+ }
+ err = config.LoadData(patchedConfigJSON, &deltaRaw)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read the patched config: %w", err)
+ }
+ patchedRaw, err := config.MergeJSONs(baseRaw, deltaRaw)
+ if err != nil {
+ return nil, fmt.Errorf("failed to merge the configs: %w", err)
+ }
+ patched, err := mgrconfig.LoadPartialData(patchedRaw)
+ if err != nil {
+ return nil, fmt.Errorf("failed to load the config: %w", err)
+ }
+ err = applyFuzzConfig(patched, cfg)
+ if err != nil {
+ return nil, err
+ }
+ return patched, nil
+}
+
+func applyFuzzConfig(mgrCfg *mgrconfig.Config, cfg *api.FuzzConfig) error {
+ if len(cfg.Focus) == 0 {
+ noFocus(mgrCfg)
+ return nil
+ }
+ for _, focus := range cfg.Focus {
+ cb := setFocus[focus]
+ if cb == nil {
+ return fmt.Errorf("unknown focus: %s", focus)
+ }
+ err := cb(mgrCfg)
+ if err != nil {
+ return fmt.Errorf("failed to apply focus %s: %w", focus, err)
+ }
+ }
+ return nil
+}
+
+// nolint: lll
+var setFocus = map[string]func(*mgrconfig.Config) error{
+ api.FocusKVM: func(mgrCfg *mgrconfig.Config) error {
+ mgrCfg.EnabledSyscalls = append(mgrCfg.EnabledSyscalls,
+ "openat$kvm",
+ "openat$sev",
+ "close",
+ "ioctl$KVM*",
+ "syz_kvm*",
+ "mmap$KVM_VCPU",
+ "munmap",
+ "syz_memcpy_off$KVM_EXIT_MMIO",
+ "syz_memcpy_off$KVM_EXIT_HYPERCALL",
+ "eventfd2",
+ "write$eventfd",
+ )
+ var err error
+ mgrCfg.VM, err = config.MergeJSONs(mgrCfg.VM, []byte(
+ `{"qemu_args": "-machine q35,nvdimm=on,accel=kvm,kernel-irqchip=split -cpu max,migratable=off -enable-kvm -smp 2,sockets=2,cores=1"}`))
+ return err
+ },
+ api.FocusNet: func(mgrCfg *mgrconfig.Config) error {
+ mgrCfg.EnabledSyscalls = append(mgrCfg.EnabledSyscalls,
+ "accept", "accept4", "bind", "close", "connect", "epoll_create",
+ "epoll_create1", "epoll_ctl", "epoll_pwait", "epoll_wait",
+ "getpeername", "getsockname", "getsockopt", "ioctl", "listen",
+ "mmap", "poll", "ppoll", "pread64", "preadv", "pselect6",
+ "pwrite64", "pwritev", "read", "readv", "recvfrom", "recvmmsg",
+ "recvmsg", "select", "sendfile", "sendmmsg", "sendmsg", "sendto",
+ "setsockopt", "shutdown", "socket", "socketpair", "splice",
+ "vmsplice", "write", "writev", "tee", "bpf", "getpid",
+ "getgid", "getuid", "gettid", "unshare", "pipe",
+ "syz_emit_ethernet", "syz_extract_tcp_res",
+ "syz_genetlink_get_family_id", "syz_init_net_socket",
+ "mkdirat$cgroup*", "openat$cgroup*", "write$cgroup*",
+ "clock_gettime", "bpf", "openat$tun", "openat$ppp",
+ "syz_open_procfs$namespace", "syz_80211_*", "nanosleep",
+ "openat$nci", "ioctl$IOCTL_GET_NCIDEV_IDX", "openat$rfkill",
+ "openat$6lowpan*", "openat$pidfd", "openat$tcp*", "openat$vhost_vsock",
+ "openat$ptp*", "ioctl$PTP*",
+ )
+ return nil
+ },
+ api.FocusFS: func(mgrCfg *mgrconfig.Config) error {
+ mgrCfg.EnabledSyscalls = append(mgrCfg.EnabledSyscalls,
+ "syz_mount_image", "open", "openat", "creat", "close", "read",
+ "pread64", "readv", "preadv", "preadv2", "write", "pwrite64",
+ "writev", "pwritev", "pwritev2", "lseek", "copy_file_range", "dup",
+ "dup2", "dup3", "tee", "splice", "vmsplice", "sendfile", "stat",
+ "lstat", "fstat", "newfstatat", "statx", "poll", "clock_gettime",
+ "ppoll", "select", "pselect6", "epoll_create", "epoll_create1",
+ "epoll_ctl", "epoll_wait", "epoll_pwait", "epoll_pwait2", "mmap",
+ "munmap", "mremap", "msync", "readahead", "fcntl", "mknod", "mknodat",
+ "chmod", "fchmod", "fchmodat", "chown", "lchown", "fchown",
+ "fchownat", "fallocate", "faccessat", "faccessat2", "utime", "utimes",
+ "futimesat", "utimensat", "link", "linkat", "symlinkat", "symlink",
+ "unlink", "unlinkat", "readlink", "readlinkat", "rename", "renameat",
+ "renameat2", "mkdir", "mkdirat", "rmdir", "truncate", "ftruncate",
+ "flock", "fsync", "fdatasync", "sync", "syncfs", "sync_file_range",
+ "getdents", "getdents64", "name_to_handle_at", "open_by_handle_at",
+ "chroot", "getcwd", "chdir", "fchdir", "quotactl", "pivot_root",
+ "statfs", "fstatfs", "syz_open_procfs", "syz_read_part_table",
+ "mount", "fsopen", "fspick", "fsconfig", "fsmount", "move_mount",
+ "open_tree", "mount_setattr", "ioctl$FS_*", "ioctl$BTRFS*",
+ "ioctl$AUTOFS*", "ioctl$EXT4*", "ioctl$F2FS*", "ioctl$FAT*",
+ "ioctl$VFAT*", "ioctl$FI*",
+ )
+ mgrCfg.NoMutateSyscalls = append(mgrCfg.NoMutateSyscalls,
+ "syz_mount_image$btrfs",
+ "syz_mount_image$ext4",
+ "syz_mount_image$f2fs",
+ "syz_mount_image$ntfs",
+ "syz_mount_image$ocfs2",
+ "syz_mount_image$xfs",
+ )
+ return nil
+ },
+ api.FocusIoUring: func(mgrCfg *mgrconfig.Config) error {
+ mgrCfg.EnabledSyscalls = append(mgrCfg.EnabledSyscalls,
+ "io_uring_*", "syz_io_uring_*", "syz_memcpy_off", "mmap", "madvise",
+ "mprotect", "eventfd", "socket", "setsockopt", "accept", "open", "close",
+ "clock_gettime", "ioctl$sock_SIOCGIFINDEX", "ioctl$IOCTL_GET_NCIDEV_IDX",
+ "openat", "epoll_create",
+ )
+ return nil
+ },
+ api.FocusBPF: func(mgrCfg *mgrconfig.Config) error {
+ mgrCfg.EnabledSyscalls = append(mgrCfg.EnabledSyscalls,
+ "bpf", "mkdir", "mount$bpf", "unlink", "close",
+ "perf_event_open*", "ioctl$PERF*", "getpid", "gettid",
+ "socketpair", "sendmsg", "recvmsg", "setsockopt$sock_attach_bpf",
+ "socket", "ioctl$sock_kcm*", "syz_clone",
+ "mkdirat$cgroup*", "openat$cgroup*", "write$cgroup*",
+ "openat$tun", "write$tun", "ioctl$TUN*", "ioctl$SIOCSIFHWADDR",
+ "openat$ppp", "syz_open_procfs$namespace", "openat$pidfd", "fstat",
+ )
+ return nil
+ },
+}
+
+func noFocus(mgrCfg *mgrconfig.Config) {
+ mgrCfg.DisabledSyscalls = []string{"perf_event_open*", "syz_mount_image$hfs", "syz_mount_image$gfs*"}
+}
diff --git a/syz-cluster/pkg/fuzzconfig/generate_test.go b/syz-cluster/pkg/fuzzconfig/generate_test.go
new file mode 100644
index 000000000..1dd143eaf
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/generate_test.go
@@ -0,0 +1,79 @@
+// Copyright 2025 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package fuzzconfig
+
+import (
+ "encoding/json"
+ "flag"
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/google/syzkaller/pkg/config"
+ "github.com/google/syzkaller/pkg/mgrconfig"
+ "github.com/google/syzkaller/syz-cluster/pkg/api"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+var flagWrite = flag.Bool("write", false, "overwrite out.txt files")
+
+func TestSingularFocus(t *testing.T) {
+ focusMap := map[string]struct{}{}
+ for _, target := range api.FuzzTargets {
+ for _, campaign := range target.Campaigns {
+ if campaign.Focus != "" {
+ focusMap[campaign.Focus] = struct{}{}
+ }
+ }
+ }
+ for focus := range focusMap {
+ t.Run(focus, func(t *testing.T) {
+ cfg := &api.FuzzConfig{Focus: []string{focus}}
+ runTest(t, cfg, filepath.Join("testdata", "singular", focus))
+ })
+ }
+}
+
+func TestNoFocus(t *testing.T) {
+ runTest(t, &api.FuzzConfig{}, filepath.Join("testdata", "singular", "default"))
+}
+
+func TestMultipleFocus(t *testing.T) {
+ runTest(t, &api.FuzzConfig{
+ Focus: []string{api.FocusBPF, api.FocusIoUring},
+ }, filepath.Join("testdata", "mixed", "bpf_io_uring"))
+}
+
+func runTest(t *testing.T, cfg *api.FuzzConfig, baseName string) {
+ base, err := GenerateBase(cfg)
+ require.NoError(t, err)
+ compareOrSave(t, baseName+".base.cfg", base)
+
+ patched, err := GeneratePatched(cfg)
+ require.NoError(t, err)
+ compareOrSave(t, baseName+".patched.cfg", patched)
+}
+
+func compareOrSave(t *testing.T, fileName string, mgrCfg *mgrconfig.Config) {
+ targetJSON, err := json.MarshalIndent(mgrCfg, "", "\t")
+ require.NoError(t, err)
+ if *flagWrite {
+ err = os.WriteFile(fileName, targetJSON, 0644)
+ require.NoError(t, err)
+ return
+ }
+
+ var raw json.RawMessage
+ err = config.LoadFile(fileName, &raw)
+ require.NoError(t, err)
+
+ cfg, err := mgrconfig.LoadPartialData(raw)
+ require.NoError(t, err)
+ require.NotNil(t, cfg)
+
+ resultJSON, err := json.MarshalIndent(cfg, "", "\t")
+ require.NoError(t, err)
+ assert.Equal(t, targetJSON, resultJSON)
+}
diff --git a/syz-cluster/workflow/configs/all/patched.cfg b/syz-cluster/pkg/fuzzconfig/patched.cfg
index 8b4027891..8b4027891 100644
--- a/syz-cluster/workflow/configs/all/patched.cfg
+++ b/syz-cluster/pkg/fuzzconfig/patched.cfg
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/mixed/bpf_io_uring.base.cfg b/syz-cluster/pkg/fuzzconfig/testdata/mixed/bpf_io_uring.base.cfg
new file mode 100644
index 000000000..6c4b3d58e
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/mixed/bpf_io_uring.base.cfg
@@ -0,0 +1,90 @@
+{
+ "name": "base",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/base/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/base/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "bpf",
+ "mkdir",
+ "mount$bpf",
+ "unlink",
+ "close",
+ "perf_event_open*",
+ "ioctl$PERF*",
+ "getpid",
+ "gettid",
+ "socketpair",
+ "sendmsg",
+ "recvmsg",
+ "setsockopt$sock_attach_bpf",
+ "socket",
+ "ioctl$sock_kcm*",
+ "syz_clone",
+ "mkdirat$cgroup*",
+ "openat$cgroup*",
+ "write$cgroup*",
+ "openat$tun",
+ "write$tun",
+ "ioctl$TUN*",
+ "ioctl$SIOCSIFHWADDR",
+ "openat$ppp",
+ "syz_open_procfs$namespace",
+ "openat$pidfd",
+ "fstat",
+ "io_uring_*",
+ "syz_io_uring_*",
+ "syz_memcpy_off",
+ "mmap",
+ "madvise",
+ "mprotect",
+ "eventfd",
+ "socket",
+ "setsockopt",
+ "accept",
+ "open",
+ "close",
+ "clock_gettime",
+ "ioctl$sock_SIOCGIFINDEX",
+ "ioctl$IOCTL_GET_NCIDEV_IDX",
+ "openat",
+ "epoll_create"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "count": 3,
+ "cmdline": "root=/dev/sda1",
+ "kernel": "/base/kernel",
+ "cpu": 2,
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/mixed/bpf_io_uring.patched.cfg b/syz-cluster/pkg/fuzzconfig/testdata/mixed/bpf_io_uring.patched.cfg
new file mode 100644
index 000000000..ce1ee850a
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/mixed/bpf_io_uring.patched.cfg
@@ -0,0 +1,90 @@
+{
+ "name": "patched",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/patched/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/patched/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "bpf",
+ "mkdir",
+ "mount$bpf",
+ "unlink",
+ "close",
+ "perf_event_open*",
+ "ioctl$PERF*",
+ "getpid",
+ "gettid",
+ "socketpair",
+ "sendmsg",
+ "recvmsg",
+ "setsockopt$sock_attach_bpf",
+ "socket",
+ "ioctl$sock_kcm*",
+ "syz_clone",
+ "mkdirat$cgroup*",
+ "openat$cgroup*",
+ "write$cgroup*",
+ "openat$tun",
+ "write$tun",
+ "ioctl$TUN*",
+ "ioctl$SIOCSIFHWADDR",
+ "openat$ppp",
+ "syz_open_procfs$namespace",
+ "openat$pidfd",
+ "fstat",
+ "io_uring_*",
+ "syz_io_uring_*",
+ "syz_memcpy_off",
+ "mmap",
+ "madvise",
+ "mprotect",
+ "eventfd",
+ "socket",
+ "setsockopt",
+ "accept",
+ "open",
+ "close",
+ "clock_gettime",
+ "ioctl$sock_SIOCGIFINDEX",
+ "ioctl$IOCTL_GET_NCIDEV_IDX",
+ "openat",
+ "epoll_create"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "cmdline": "root=/dev/sda1",
+ "count": 9,
+ "cpu": 2,
+ "kernel": "/patched/kernel",
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/bpf.base.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/bpf.base.cfg
new file mode 100644
index 000000000..79d1339c0
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/bpf.base.cfg
@@ -0,0 +1,73 @@
+{
+ "name": "base",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/base/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/base/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "bpf",
+ "mkdir",
+ "mount$bpf",
+ "unlink",
+ "close",
+ "perf_event_open*",
+ "ioctl$PERF*",
+ "getpid",
+ "gettid",
+ "socketpair",
+ "sendmsg",
+ "recvmsg",
+ "setsockopt$sock_attach_bpf",
+ "socket",
+ "ioctl$sock_kcm*",
+ "syz_clone",
+ "mkdirat$cgroup*",
+ "openat$cgroup*",
+ "write$cgroup*",
+ "openat$tun",
+ "write$tun",
+ "ioctl$TUN*",
+ "ioctl$SIOCSIFHWADDR",
+ "openat$ppp",
+ "syz_open_procfs$namespace",
+ "openat$pidfd",
+ "fstat"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "count": 3,
+ "cmdline": "root=/dev/sda1",
+ "kernel": "/base/kernel",
+ "cpu": 2,
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/bpf.patched.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/bpf.patched.cfg
new file mode 100644
index 000000000..059b47cf0
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/bpf.patched.cfg
@@ -0,0 +1,73 @@
+{
+ "name": "patched",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/patched/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/patched/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "bpf",
+ "mkdir",
+ "mount$bpf",
+ "unlink",
+ "close",
+ "perf_event_open*",
+ "ioctl$PERF*",
+ "getpid",
+ "gettid",
+ "socketpair",
+ "sendmsg",
+ "recvmsg",
+ "setsockopt$sock_attach_bpf",
+ "socket",
+ "ioctl$sock_kcm*",
+ "syz_clone",
+ "mkdirat$cgroup*",
+ "openat$cgroup*",
+ "write$cgroup*",
+ "openat$tun",
+ "write$tun",
+ "ioctl$TUN*",
+ "ioctl$SIOCSIFHWADDR",
+ "openat$ppp",
+ "syz_open_procfs$namespace",
+ "openat$pidfd",
+ "fstat"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "cmdline": "root=/dev/sda1",
+ "count": 9,
+ "cpu": 2,
+ "kernel": "/patched/kernel",
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/default.base.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/default.base.cfg
new file mode 100644
index 000000000..28c8c600d
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/default.base.cfg
@@ -0,0 +1,49 @@
+{
+ "name": "base",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/base/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/base/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "disable_syscalls": [
+ "perf_event_open*",
+ "syz_mount_image$hfs",
+ "syz_mount_image$gfs*"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "count": 3,
+ "cmdline": "root=/dev/sda1",
+ "kernel": "/base/kernel",
+ "cpu": 2,
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/default.patched.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/default.patched.cfg
new file mode 100644
index 000000000..55d699651
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/default.patched.cfg
@@ -0,0 +1,49 @@
+{
+ "name": "patched",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/patched/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/patched/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "disable_syscalls": [
+ "perf_event_open*",
+ "syz_mount_image$hfs",
+ "syz_mount_image$gfs*"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "cmdline": "root=/dev/sda1",
+ "count": 9,
+ "cpu": 2,
+ "kernel": "/patched/kernel",
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/fs.base.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/fs.base.cfg
new file mode 100644
index 000000000..8515dfe19
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/fs.base.cfg
@@ -0,0 +1,168 @@
+{
+ "name": "base",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/base/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/base/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "syz_mount_image",
+ "open",
+ "openat",
+ "creat",
+ "close",
+ "read",
+ "pread64",
+ "readv",
+ "preadv",
+ "preadv2",
+ "write",
+ "pwrite64",
+ "writev",
+ "pwritev",
+ "pwritev2",
+ "lseek",
+ "copy_file_range",
+ "dup",
+ "dup2",
+ "dup3",
+ "tee",
+ "splice",
+ "vmsplice",
+ "sendfile",
+ "stat",
+ "lstat",
+ "fstat",
+ "newfstatat",
+ "statx",
+ "poll",
+ "clock_gettime",
+ "ppoll",
+ "select",
+ "pselect6",
+ "epoll_create",
+ "epoll_create1",
+ "epoll_ctl",
+ "epoll_wait",
+ "epoll_pwait",
+ "epoll_pwait2",
+ "mmap",
+ "munmap",
+ "mremap",
+ "msync",
+ "readahead",
+ "fcntl",
+ "mknod",
+ "mknodat",
+ "chmod",
+ "fchmod",
+ "fchmodat",
+ "chown",
+ "lchown",
+ "fchown",
+ "fchownat",
+ "fallocate",
+ "faccessat",
+ "faccessat2",
+ "utime",
+ "utimes",
+ "futimesat",
+ "utimensat",
+ "link",
+ "linkat",
+ "symlinkat",
+ "symlink",
+ "unlink",
+ "unlinkat",
+ "readlink",
+ "readlinkat",
+ "rename",
+ "renameat",
+ "renameat2",
+ "mkdir",
+ "mkdirat",
+ "rmdir",
+ "truncate",
+ "ftruncate",
+ "flock",
+ "fsync",
+ "fdatasync",
+ "sync",
+ "syncfs",
+ "sync_file_range",
+ "getdents",
+ "getdents64",
+ "name_to_handle_at",
+ "open_by_handle_at",
+ "chroot",
+ "getcwd",
+ "chdir",
+ "fchdir",
+ "quotactl",
+ "pivot_root",
+ "statfs",
+ "fstatfs",
+ "syz_open_procfs",
+ "syz_read_part_table",
+ "mount",
+ "fsopen",
+ "fspick",
+ "fsconfig",
+ "fsmount",
+ "move_mount",
+ "open_tree",
+ "mount_setattr",
+ "ioctl$FS_*",
+ "ioctl$BTRFS*",
+ "ioctl$AUTOFS*",
+ "ioctl$EXT4*",
+ "ioctl$F2FS*",
+ "ioctl$FAT*",
+ "ioctl$VFAT*",
+ "ioctl$FI*"
+ ],
+ "no_mutate_syscalls": [
+ "syz_mount_image$btrfs",
+ "syz_mount_image$ext4",
+ "syz_mount_image$f2fs",
+ "syz_mount_image$ntfs",
+ "syz_mount_image$ocfs2",
+ "syz_mount_image$xfs"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "count": 3,
+ "cmdline": "root=/dev/sda1",
+ "kernel": "/base/kernel",
+ "cpu": 2,
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/fs.patched.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/fs.patched.cfg
new file mode 100644
index 000000000..9fbfaf3f6
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/fs.patched.cfg
@@ -0,0 +1,168 @@
+{
+ "name": "patched",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/patched/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/patched/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "syz_mount_image",
+ "open",
+ "openat",
+ "creat",
+ "close",
+ "read",
+ "pread64",
+ "readv",
+ "preadv",
+ "preadv2",
+ "write",
+ "pwrite64",
+ "writev",
+ "pwritev",
+ "pwritev2",
+ "lseek",
+ "copy_file_range",
+ "dup",
+ "dup2",
+ "dup3",
+ "tee",
+ "splice",
+ "vmsplice",
+ "sendfile",
+ "stat",
+ "lstat",
+ "fstat",
+ "newfstatat",
+ "statx",
+ "poll",
+ "clock_gettime",
+ "ppoll",
+ "select",
+ "pselect6",
+ "epoll_create",
+ "epoll_create1",
+ "epoll_ctl",
+ "epoll_wait",
+ "epoll_pwait",
+ "epoll_pwait2",
+ "mmap",
+ "munmap",
+ "mremap",
+ "msync",
+ "readahead",
+ "fcntl",
+ "mknod",
+ "mknodat",
+ "chmod",
+ "fchmod",
+ "fchmodat",
+ "chown",
+ "lchown",
+ "fchown",
+ "fchownat",
+ "fallocate",
+ "faccessat",
+ "faccessat2",
+ "utime",
+ "utimes",
+ "futimesat",
+ "utimensat",
+ "link",
+ "linkat",
+ "symlinkat",
+ "symlink",
+ "unlink",
+ "unlinkat",
+ "readlink",
+ "readlinkat",
+ "rename",
+ "renameat",
+ "renameat2",
+ "mkdir",
+ "mkdirat",
+ "rmdir",
+ "truncate",
+ "ftruncate",
+ "flock",
+ "fsync",
+ "fdatasync",
+ "sync",
+ "syncfs",
+ "sync_file_range",
+ "getdents",
+ "getdents64",
+ "name_to_handle_at",
+ "open_by_handle_at",
+ "chroot",
+ "getcwd",
+ "chdir",
+ "fchdir",
+ "quotactl",
+ "pivot_root",
+ "statfs",
+ "fstatfs",
+ "syz_open_procfs",
+ "syz_read_part_table",
+ "mount",
+ "fsopen",
+ "fspick",
+ "fsconfig",
+ "fsmount",
+ "move_mount",
+ "open_tree",
+ "mount_setattr",
+ "ioctl$FS_*",
+ "ioctl$BTRFS*",
+ "ioctl$AUTOFS*",
+ "ioctl$EXT4*",
+ "ioctl$F2FS*",
+ "ioctl$FAT*",
+ "ioctl$VFAT*",
+ "ioctl$FI*"
+ ],
+ "no_mutate_syscalls": [
+ "syz_mount_image$btrfs",
+ "syz_mount_image$ext4",
+ "syz_mount_image$f2fs",
+ "syz_mount_image$ntfs",
+ "syz_mount_image$ocfs2",
+ "syz_mount_image$xfs"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "cmdline": "root=/dev/sda1",
+ "count": 9,
+ "cpu": 2,
+ "kernel": "/patched/kernel",
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/io_uring.base.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/io_uring.base.cfg
new file mode 100644
index 000000000..94990b812
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/io_uring.base.cfg
@@ -0,0 +1,63 @@
+{
+ "name": "base",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/base/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/base/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "io_uring_*",
+ "syz_io_uring_*",
+ "syz_memcpy_off",
+ "mmap",
+ "madvise",
+ "mprotect",
+ "eventfd",
+ "socket",
+ "setsockopt",
+ "accept",
+ "open",
+ "close",
+ "clock_gettime",
+ "ioctl$sock_SIOCGIFINDEX",
+ "ioctl$IOCTL_GET_NCIDEV_IDX",
+ "openat",
+ "epoll_create"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "count": 3,
+ "cmdline": "root=/dev/sda1",
+ "kernel": "/base/kernel",
+ "cpu": 2,
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/io_uring.patched.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/io_uring.patched.cfg
new file mode 100644
index 000000000..4fe786944
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/io_uring.patched.cfg
@@ -0,0 +1,63 @@
+{
+ "name": "patched",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/patched/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/patched/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "io_uring_*",
+ "syz_io_uring_*",
+ "syz_memcpy_off",
+ "mmap",
+ "madvise",
+ "mprotect",
+ "eventfd",
+ "socket",
+ "setsockopt",
+ "accept",
+ "open",
+ "close",
+ "clock_gettime",
+ "ioctl$sock_SIOCGIFINDEX",
+ "ioctl$IOCTL_GET_NCIDEV_IDX",
+ "openat",
+ "epoll_create"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "cmdline": "root=/dev/sda1",
+ "count": 9,
+ "cpu": 2,
+ "kernel": "/patched/kernel",
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/kvm.base.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/kvm.base.cfg
new file mode 100644
index 000000000..bdfe653ef
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/kvm.base.cfg
@@ -0,0 +1,57 @@
+{
+ "name": "base",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/base/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/base/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "openat$kvm",
+ "openat$sev",
+ "close",
+ "ioctl$KVM*",
+ "syz_kvm*",
+ "mmap$KVM_VCPU",
+ "munmap",
+ "syz_memcpy_off$KVM_EXIT_MMIO",
+ "syz_memcpy_off$KVM_EXIT_HYPERCALL",
+ "eventfd2",
+ "write$eventfd"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "cmdline": "root=/dev/sda1",
+ "count": 3,
+ "cpu": 2,
+ "kernel": "/base/kernel",
+ "mem": 7168,
+ "qemu_args": "-machine q35,nvdimm=on,accel=kvm,kernel-irqchip=split -cpu max,migratable=off -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/kvm.patched.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/kvm.patched.cfg
new file mode 100644
index 000000000..86e319ac7
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/kvm.patched.cfg
@@ -0,0 +1,57 @@
+{
+ "name": "patched",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/patched/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/patched/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "openat$kvm",
+ "openat$sev",
+ "close",
+ "ioctl$KVM*",
+ "syz_kvm*",
+ "mmap$KVM_VCPU",
+ "munmap",
+ "syz_memcpy_off$KVM_EXIT_MMIO",
+ "syz_memcpy_off$KVM_EXIT_HYPERCALL",
+ "eventfd2",
+ "write$eventfd"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "cmdline": "root=/dev/sda1",
+ "count": 9,
+ "cpu": 2,
+ "kernel": "/patched/kernel",
+ "mem": 7168,
+ "qemu_args": "-machine q35,nvdimm=on,accel=kvm,kernel-irqchip=split -cpu max,migratable=off -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/net.base.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/net.base.cfg
new file mode 100644
index 000000000..641241acb
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/net.base.cfg
@@ -0,0 +1,118 @@
+{
+ "name": "base",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/base/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/base/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "accept",
+ "accept4",
+ "bind",
+ "close",
+ "connect",
+ "epoll_create",
+ "epoll_create1",
+ "epoll_ctl",
+ "epoll_pwait",
+ "epoll_wait",
+ "getpeername",
+ "getsockname",
+ "getsockopt",
+ "ioctl",
+ "listen",
+ "mmap",
+ "poll",
+ "ppoll",
+ "pread64",
+ "preadv",
+ "pselect6",
+ "pwrite64",
+ "pwritev",
+ "read",
+ "readv",
+ "recvfrom",
+ "recvmmsg",
+ "recvmsg",
+ "select",
+ "sendfile",
+ "sendmmsg",
+ "sendmsg",
+ "sendto",
+ "setsockopt",
+ "shutdown",
+ "socket",
+ "socketpair",
+ "splice",
+ "vmsplice",
+ "write",
+ "writev",
+ "tee",
+ "bpf",
+ "getpid",
+ "getgid",
+ "getuid",
+ "gettid",
+ "unshare",
+ "pipe",
+ "syz_emit_ethernet",
+ "syz_extract_tcp_res",
+ "syz_genetlink_get_family_id",
+ "syz_init_net_socket",
+ "mkdirat$cgroup*",
+ "openat$cgroup*",
+ "write$cgroup*",
+ "clock_gettime",
+ "bpf",
+ "openat$tun",
+ "openat$ppp",
+ "syz_open_procfs$namespace",
+ "syz_80211_*",
+ "nanosleep",
+ "openat$nci",
+ "ioctl$IOCTL_GET_NCIDEV_IDX",
+ "openat$rfkill",
+ "openat$6lowpan*",
+ "openat$pidfd",
+ "openat$tcp*",
+ "openat$vhost_vsock",
+ "openat$ptp*",
+ "ioctl$PTP*"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "count": 3,
+ "cmdline": "root=/dev/sda1",
+ "kernel": "/base/kernel",
+ "cpu": 2,
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/fuzzconfig/testdata/singular/net.patched.cfg b/syz-cluster/pkg/fuzzconfig/testdata/singular/net.patched.cfg
new file mode 100644
index 000000000..985dbb9be
--- /dev/null
+++ b/syz-cluster/pkg/fuzzconfig/testdata/singular/net.patched.cfg
@@ -0,0 +1,118 @@
+{
+ "name": "patched",
+ "target": "linux/amd64",
+ "http": "",
+ "rpc": ":0",
+ "workdir": "/workdir",
+ "kernel_obj": "/patched/obj",
+ "kernel_build_src": "/workdir",
+ "android_split_build": false,
+ "image": "/patched/image",
+ "ssh_user": "root",
+ "syzkaller": "/syzkaller",
+ "procs": 3,
+ "max_crash_logs": 100,
+ "sandbox": "none",
+ "sandbox_arg": 0,
+ "snapshot": false,
+ "cover": true,
+ "cover_filter": {},
+ "raw_cover": false,
+ "reproduce": true,
+ "preserve_corpus": true,
+ "enable_syscalls": [
+ "accept",
+ "accept4",
+ "bind",
+ "close",
+ "connect",
+ "epoll_create",
+ "epoll_create1",
+ "epoll_ctl",
+ "epoll_pwait",
+ "epoll_wait",
+ "getpeername",
+ "getsockname",
+ "getsockopt",
+ "ioctl",
+ "listen",
+ "mmap",
+ "poll",
+ "ppoll",
+ "pread64",
+ "preadv",
+ "pselect6",
+ "pwrite64",
+ "pwritev",
+ "read",
+ "readv",
+ "recvfrom",
+ "recvmmsg",
+ "recvmsg",
+ "select",
+ "sendfile",
+ "sendmmsg",
+ "sendmsg",
+ "sendto",
+ "setsockopt",
+ "shutdown",
+ "socket",
+ "socketpair",
+ "splice",
+ "vmsplice",
+ "write",
+ "writev",
+ "tee",
+ "bpf",
+ "getpid",
+ "getgid",
+ "getuid",
+ "gettid",
+ "unshare",
+ "pipe",
+ "syz_emit_ethernet",
+ "syz_extract_tcp_res",
+ "syz_genetlink_get_family_id",
+ "syz_init_net_socket",
+ "mkdirat$cgroup*",
+ "openat$cgroup*",
+ "write$cgroup*",
+ "clock_gettime",
+ "bpf",
+ "openat$tun",
+ "openat$ppp",
+ "syz_open_procfs$namespace",
+ "syz_80211_*",
+ "nanosleep",
+ "openat$nci",
+ "ioctl$IOCTL_GET_NCIDEV_IDX",
+ "openat$rfkill",
+ "openat$6lowpan*",
+ "openat$pidfd",
+ "openat$tcp*",
+ "openat$vhost_vsock",
+ "openat$ptp*",
+ "ioctl$PTP*"
+ ],
+ "strace_bin": "",
+ "strace_bin_on_target": false,
+ "execprog_bin_on_target": "",
+ "executor_bin_on_target": "",
+ "run_fsck": true,
+ "type": "qemu",
+ "vm": {
+ "cmdline": "root=/dev/sda1",
+ "count": 9,
+ "cpu": 2,
+ "kernel": "/patched/kernel",
+ "mem": 7168,
+ "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
+ },
+ "asset_storage": null,
+ "Experimental": {
+ "reset_acc_state": false,
+ "remote_cover": true,
+ "cover_edges": false,
+ "descriptions_mode": "manual"
+ }
+} \ No newline at end of file
diff --git a/syz-cluster/pkg/triage/fuzz_target.go b/syz-cluster/pkg/triage/fuzz_target.go
index 6fecc24c0..e4b6fedf3 100644
--- a/syz-cluster/pkg/triage/fuzz_target.go
+++ b/syz-cluster/pkg/triage/fuzz_target.go
@@ -4,25 +4,97 @@
package triage
import (
+ "sort"
"strings"
"github.com/google/syzkaller/syz-cluster/pkg/api"
)
-func SelectFuzzConfig(series *api.Series, fuzzConfigs []*api.FuzzTriageTarget) *api.FuzzTriageTarget {
+func SelectFuzzConfigs(series *api.Series, fuzzConfigs []*api.FuzzTriageTarget) []*api.KernelFuzzConfig {
seriesCc := map[string]bool{}
for _, cc := range series.Cc {
seriesCc[strings.ToLower(cc)] = true
}
+ var ret, defaultRet []*api.KernelFuzzConfig
for _, config := range fuzzConfigs {
intersects := false
for _, cc := range config.EmailLists {
intersects = intersects || seriesCc[cc]
}
- if len(config.EmailLists) != 0 && !intersects {
- continue
+ if intersects {
+ ret = append(ret, config.Campaigns...)
+ } else if len(config.EmailLists) == 0 {
+ defaultRet = append(defaultRet, config.Campaigns...)
}
- return config
}
- return nil
+ // We want to return the fallback option only if no element matched exactly.
+ if len(ret) > 0 {
+ return ret
+ }
+ return defaultRet
+}
+
+type MergedFuzzConfig struct {
+ KernelConfig string
+ FuzzConfig *api.FuzzConfig
+}
+
+func MergeKernelFuzzConfigs(configs []*api.KernelFuzzConfig) []*MergedFuzzConfig {
+ type groupKey struct {
+ config string
+ track string
+ bugTitleRe string
+ }
+ groups := map[groupKey][]*api.KernelFuzzConfig{}
+ var orderedKeys []groupKey
+ for _, config := range configs {
+ // Some of the different fuzz configs may still be merged together,
+ // e.g. if they only differ in the syscall lists and corpuses.
+ key := groupKey{config.KernelConfig, config.Track, config.BugTitleRe}
+ if _, ok := groups[key]; !ok {
+ orderedKeys = append(orderedKeys, key)
+ }
+ groups[key] = append(groups[key], config)
+ }
+ var ret []*MergedFuzzConfig
+ for _, key := range orderedKeys {
+ // TODO: is there way to auto-generate a prefix?
+ ret = append(ret, &MergedFuzzConfig{
+ KernelConfig: key.config,
+ FuzzConfig: mergeFuzzConfigs(groups[key]),
+ })
+ }
+ return ret
+}
+
+func mergeFuzzConfigs(configs []*api.KernelFuzzConfig) *api.FuzzConfig {
+ var ret api.FuzzConfig
+ for _, config := range configs {
+ if config.Focus != "" {
+ ret.Focus = append(ret.Focus, config.Focus)
+ }
+ if config.CorpusURL != "" {
+ ret.CorpusURLs = append(ret.CorpusURLs, config.CorpusURL)
+ }
+ ret.SkipCoverCheck = ret.SkipCoverCheck || config.SkipCoverCheck
+ // Must be the same.
+ ret.BugTitleRe = config.BugTitleRe
+ ret.Track = config.Track
+ }
+ ret.Focus = unique(ret.Focus)
+ ret.CorpusURLs = unique(ret.CorpusURLs)
+ return &ret
+}
+
+func unique(list []string) []string {
+ seen := make(map[string]struct{}, len(list))
+ for _, s := range list {
+ seen[s] = struct{}{}
+ }
+ var unique []string
+ for s := range seen {
+ unique = append(unique, s)
+ }
+ sort.Strings(unique)
+ return unique
}
diff --git a/syz-cluster/pkg/triage/fuzz_target_test.go b/syz-cluster/pkg/triage/fuzz_target_test.go
index fa7039bda..6b5111e0c 100644
--- a/syz-cluster/pkg/triage/fuzz_target_test.go
+++ b/syz-cluster/pkg/triage/fuzz_target_test.go
@@ -10,32 +10,126 @@ import (
"github.com/stretchr/testify/assert"
)
-func TestSelectFuzzConfig(t *testing.T) {
- bpf := &api.FuzzTriageTarget{EmailLists: []string{"bpf@list"}}
- net := &api.FuzzTriageTarget{EmailLists: []string{"net@list"}}
- mainline := &api.FuzzTriageTarget{EmailLists: nil}
- configs := []*api.FuzzTriageTarget{bpf, net, mainline}
+func TestSelectFuzzConfigs(t *testing.T) {
+ bpf, bpfKmsan, net, mainline := &api.KernelFuzzConfig{},
+ &api.KernelFuzzConfig{},
+ &api.KernelFuzzConfig{},
+ &api.KernelFuzzConfig{}
+ configs := []*api.FuzzTriageTarget{
+ {
+ EmailLists: []string{"bpf@list"},
+ Campaigns: []*api.KernelFuzzConfig{bpf, bpfKmsan},
+ },
+ {
+ EmailLists: []string{"net@list"},
+ Campaigns: []*api.KernelFuzzConfig{net},
+ },
+ {
+ EmailLists: nil,
+ Campaigns: []*api.KernelFuzzConfig{mainline},
+ },
+ }
tests := []struct {
testName string
- result *api.FuzzTriageTarget
+ result []*api.KernelFuzzConfig
series *api.Series
}{
{
- testName: "select-first",
- result: bpf,
+ testName: "select-one",
+ result: []*api.KernelFuzzConfig{net},
+ series: &api.Series{Cc: []string{"net@list"}},
+ },
+ {
+ testName: "select-both",
+ result: []*api.KernelFuzzConfig{bpf, bpfKmsan, net},
series: &api.Series{Cc: []string{"bpf@list", "net@list"}},
},
{
testName: "fallback",
- result: mainline,
+ result: []*api.KernelFuzzConfig{mainline},
series: &api.Series{Cc: []string{"unknown@list"}},
},
}
for _, test := range tests {
t.Run(test.testName, func(t *testing.T) {
- ret := SelectFuzzConfig(test.series, configs)
+ ret := SelectFuzzConfigs(test.series, configs)
assert.Equal(t, test.result, ret)
})
}
}
+
+func TestMergeKernelFuzzConfigs(t *testing.T) {
+ t.Run("split", func(t *testing.T) {
+ assert.Equal(t, []*MergedFuzzConfig{
+ {
+ KernelConfig: "kasan_config",
+ FuzzConfig: &api.FuzzConfig{
+ Track: "KASAN",
+ Focus: []string{"net"},
+ },
+ },
+ {
+ KernelConfig: "kmsan_config",
+ FuzzConfig: &api.FuzzConfig{
+ Track: "KMSAN",
+ Focus: []string{"net"},
+ },
+ },
+ }, MergeKernelFuzzConfigs([]*api.KernelFuzzConfig{
+ {
+ Track: "KASAN",
+ KernelConfig: "kasan_config",
+ Focus: "net",
+ },
+ {
+ Track: "KMSAN",
+ KernelConfig: "kmsan_config",
+ Focus: "net",
+ },
+ }))
+ })
+ t.Run("merge", func(t *testing.T) {
+ assert.Equal(t, []*MergedFuzzConfig{
+ {
+ KernelConfig: "kasan_config",
+ FuzzConfig: &api.FuzzConfig{
+ Track: "KASAN",
+ Focus: []string{"bpf", "net"},
+ },
+ },
+ }, MergeKernelFuzzConfigs([]*api.KernelFuzzConfig{
+ {
+ Track: "KASAN",
+ KernelConfig: "kasan_config",
+ Focus: "net",
+ },
+ {
+ Track: "KASAN",
+ KernelConfig: "kasan_config",
+ Focus: "bpf",
+ },
+ }))
+ })
+}
+
+func TestMergeFuzzConfigs(t *testing.T) {
+ assert.Equal(t, &api.FuzzConfig{
+ Focus: []string{"bpf", "net"},
+ CorpusURLs: []string{"url1", "url2"},
+ SkipCoverCheck: true,
+ BugTitleRe: "regexp",
+ }, mergeFuzzConfigs([]*api.KernelFuzzConfig{
+ {
+ Focus: "net",
+ CorpusURL: "url2",
+ BugTitleRe: "regexp",
+ },
+ {
+ Focus: "bpf",
+ CorpusURL: "url1",
+ BugTitleRe: "regexp",
+ SkipCoverCheck: true,
+ },
+ }))
+}
diff --git a/syz-cluster/workflow/boot-step/Dockerfile b/syz-cluster/workflow/boot-step/Dockerfile
index 5bb1245b7..573b13593 100644
--- a/syz-cluster/workflow/boot-step/Dockerfile
+++ b/syz-cluster/workflow/boot-step/Dockerfile
@@ -39,6 +39,5 @@ RUN useradd --create-home syzkaller
COPY --from=syzkaller-builder /build/bin/ /syzkaller/bin/
COPY --from=boot-step-builder /bin/boot-step /bin/boot-step
-COPY syz-cluster/workflow/configs/ /configs/
ENTRYPOINT ["/bin/boot-step"]
diff --git a/syz-cluster/workflow/boot-step/main.go b/syz-cluster/workflow/boot-step/main.go
index 1711ee961..b2001a13c 100644
--- a/syz-cluster/workflow/boot-step/main.go
+++ b/syz-cluster/workflow/boot-step/main.go
@@ -8,7 +8,6 @@ import (
"flag"
"fmt"
"log"
- "path/filepath"
"github.com/google/syzkaller/pkg/instance"
"github.com/google/syzkaller/pkg/mgrconfig"
@@ -16,6 +15,7 @@ import (
"github.com/google/syzkaller/pkg/report"
"github.com/google/syzkaller/syz-cluster/pkg/api"
"github.com/google/syzkaller/syz-cluster/pkg/app"
+ "github.com/google/syzkaller/syz-cluster/pkg/fuzzconfig"
)
var (
@@ -80,7 +80,7 @@ const retryCount = 3
const vmCount = 3
func runTest(ctx context.Context, client *api.Client) (bool, error) {
- cfg, err := mgrconfig.LoadFile(filepath.Join("/configs", *flagConfig, "base.cfg"))
+ cfg, err := fuzzconfig.GenerateBase(&api.FuzzConfig{})
if err != nil {
return false, err
}
@@ -88,6 +88,9 @@ func runTest(ctx context.Context, client *api.Client) (bool, error) {
return false, err
}
cfg.Workdir = "/tmp/test-workdir"
+ if err := mgrconfig.Complete(cfg); err != nil {
+ return false, fmt.Errorf("failed to complete the config: %w", err)
+ }
var rep *report.Report
for i := 0; i < retryCount; i++ {
diff --git a/syz-cluster/workflow/configs/bpf/base.cfg b/syz-cluster/workflow/configs/bpf/base.cfg
deleted file mode 100644
index 6dfa3b596..000000000
--- a/syz-cluster/workflow/configs/bpf/base.cfg
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "name": "base",
- "target": "linux/amd64",
- "kernel_obj": "/base/obj",
- "kernel_build_src": "/workdir",
- "image": "/base/image",
- "syzkaller": "/syzkaller",
- "workdir": "/workdir",
- "type": "qemu",
- "enable_syscalls": [
- "bpf", "mkdir", "mount$bpf", "unlink", "close",
- "perf_event_open*", "ioctl$PERF*", "getpid", "gettid",
- "socketpair", "sendmsg", "recvmsg", "setsockopt$sock_attach_bpf",
- "socket", "ioctl$sock_kcm*", "syz_clone",
- "mkdirat$cgroup*", "openat$cgroup*", "write$cgroup*",
- "openat$tun", "write$tun", "ioctl$TUN*", "ioctl$SIOCSIFHWADDR",
- "openat$ppp", "syz_open_procfs$namespace", "openat$pidfd", "fstat"
- ],
- "procs": 3,
- "sandbox": "none",
- "experimental": {"cover_edges": false},
- "vm": {
- "count": 3,
- "cmdline": "root=/dev/sda1",
- "kernel": "/base/kernel",
- "cpu": 2,
- "mem": 7168,
- "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
- }
-}
diff --git a/syz-cluster/workflow/configs/bpf/patched.cfg b/syz-cluster/workflow/configs/bpf/patched.cfg
deleted file mode 100644
index 8b4027891..000000000
--- a/syz-cluster/workflow/configs/bpf/patched.cfg
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "patched",
- "target": "linux/amd64",
- "kernel_obj": "/patched/obj",
- "image": "/patched/image",
- "vm": {
- "count": 9,
- "kernel": "/patched/kernel"
- }
-}
diff --git a/syz-cluster/workflow/configs/fs/base.cfg b/syz-cluster/workflow/configs/fs/base.cfg
deleted file mode 100644
index 2090ca8b3..000000000
--- a/syz-cluster/workflow/configs/fs/base.cfg
+++ /dev/null
@@ -1,52 +0,0 @@
-{
- "name": "base",
- "target": "linux/amd64",
- "kernel_obj": "/base/obj",
- "kernel_build_src": "/workdir",
- "image": "/base/image",
- "syzkaller": "/syzkaller",
- "workdir": "/workdir",
- "type": "qemu",
- "enable_syscalls": [
- "syz_mount_image", "open", "openat", "creat", "close", "read",
- "pread64", "readv", "preadv", "preadv2", "write", "pwrite64",
- "writev", "pwritev", "pwritev2", "lseek", "copy_file_range", "dup",
- "dup2", "dup3", "tee", "splice", "vmsplice", "sendfile", "stat",
- "lstat", "fstat", "newfstatat", "statx", "poll", "clock_gettime",
- "ppoll", "select", "pselect6", "epoll_create", "epoll_create1",
- "epoll_ctl", "epoll_wait", "epoll_pwait", "epoll_pwait2", "mmap",
- "munmap", "mremap", "msync", "readahead", "fcntl", "mknod", "mknodat",
- "chmod", "fchmod", "fchmodat", "chown", "lchown", "fchown",
- "fchownat", "fallocate", "faccessat", "faccessat2", "utime", "utimes",
- "futimesat", "utimensat", "link", "linkat", "symlinkat", "symlink",
- "unlink", "unlinkat", "readlink", "readlinkat", "rename", "renameat",
- "renameat2", "mkdir", "mkdirat", "rmdir", "truncate", "ftruncate",
- "flock", "fsync", "fdatasync", "sync", "syncfs", "sync_file_range",
- "getdents", "getdents64", "name_to_handle_at", "open_by_handle_at",
- "chroot", "getcwd", "chdir", "fchdir", "quotactl", "pivot_root",
- "statfs", "fstatfs", "syz_open_procfs", "syz_read_part_table",
- "mount", "fsopen", "fspick", "fsconfig", "fsmount", "move_mount",
- "open_tree", "mount_setattr", "ioctl$FS_*", "ioctl$BTRFS*",
- "ioctl$AUTOFS*", "ioctl$EXT4*", "ioctl$F2FS*", "ioctl$FAT*",
- "ioctl$VFAT*", "ioctl$FI*"
- ],
- "no_mutate_syscalls": [
- "syz_mount_image$btrfs",
- "syz_mount_image$ext4",
- "syz_mount_image$f2fs",
- "syz_mount_image$ntfs",
- "syz_mount_image$ocfs2",
- "syz_mount_image$xfs"
- ],
- "procs": 3,
- "sandbox": "none",
- "experimental": {"cover_edges": false},
- "vm": {
- "count": 3,
- "cmdline": "root=/dev/sda1",
- "kernel": "/base/kernel",
- "cpu": 2,
- "mem": 7168,
- "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
- }
-}
diff --git a/syz-cluster/workflow/configs/fs/patched.cfg b/syz-cluster/workflow/configs/fs/patched.cfg
deleted file mode 100644
index 8b4027891..000000000
--- a/syz-cluster/workflow/configs/fs/patched.cfg
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "patched",
- "target": "linux/amd64",
- "kernel_obj": "/patched/obj",
- "image": "/patched/image",
- "vm": {
- "count": 9,
- "kernel": "/patched/kernel"
- }
-}
diff --git a/syz-cluster/workflow/configs/io-uring/base.cfg b/syz-cluster/workflow/configs/io-uring/base.cfg
deleted file mode 100644
index ebee35fa4..000000000
--- a/syz-cluster/workflow/configs/io-uring/base.cfg
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "name": "base",
- "target": "linux/amd64",
- "kernel_obj": "/base/obj",
- "kernel_build_src": "/workdir",
- "image": "/base/image",
- "syzkaller": "/syzkaller",
- "workdir": "/workdir",
- "type": "qemu",
- "enable_syscalls": [
- "io_uring_*", "syz_io_uring_*", "syz_memcpy_off", "mmap", "madvise",
- "mprotect", "eventfd", "socket", "setsockopt", "accept", "open", "close",
- "clock_gettime", "ioctl$sock_SIOCGIFINDEX", "ioctl$IOCTL_GET_NCIDEV_IDX",
- "openat", "epoll_create"
- ],
- "procs": 3,
- "sandbox": "none",
- "experimental": {"cover_edges": false},
- "vm": {
- "count": 3,
- "cmdline": "root=/dev/sda1",
- "kernel": "/base/kernel",
- "cpu": 2,
- "mem": 7168,
- "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
- }
-}
diff --git a/syz-cluster/workflow/configs/io-uring/patched.cfg b/syz-cluster/workflow/configs/io-uring/patched.cfg
deleted file mode 100644
index 8b4027891..000000000
--- a/syz-cluster/workflow/configs/io-uring/patched.cfg
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "patched",
- "target": "linux/amd64",
- "kernel_obj": "/patched/obj",
- "image": "/patched/image",
- "vm": {
- "count": 9,
- "kernel": "/patched/kernel"
- }
-}
diff --git a/syz-cluster/workflow/configs/kvm/base.cfg b/syz-cluster/workflow/configs/kvm/base.cfg
deleted file mode 100644
index e70b13601..000000000
--- a/syz-cluster/workflow/configs/kvm/base.cfg
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "name": "base",
- "target": "linux/amd64",
- "kernel_obj": "/base/obj",
- "kernel_build_src": "/workdir",
- "image": "/base/image",
- "syzkaller": "/syzkaller",
- "workdir": "/workdir",
- "type": "qemu",
- "enable_syscalls": [
- "openat$kvm",
- "openat$sev",
- "close",
- "ioctl$KVM*",
- "syz_kvm*",
- "mmap$KVM_VCPU",
- "munmap",
- "syz_memcpy_off$KVM_EXIT_MMIO",
- "syz_memcpy_off$KVM_EXIT_HYPERCALL",
- "eventfd2",
- "write$eventfd"
- ],
- "procs": 3,
- "sandbox": "none",
- "experimental": {"cover_edges": false},
- "vm": {
- "count": 3,
- "cmdline": "root=/dev/sda1 kvm-intel.nested=1",
- "kernel": "/base/kernel",
- "cpu": 2,
- "mem": 7168,
- "qemu_args": "-machine q35,nvdimm=on,accel=kvm,kernel-irqchip=split -cpu max,migratable=off -enable-kvm -smp 2,sockets=2,cores=1"
- }
-}
diff --git a/syz-cluster/workflow/configs/kvm/patched.cfg b/syz-cluster/workflow/configs/kvm/patched.cfg
deleted file mode 100644
index 8b4027891..000000000
--- a/syz-cluster/workflow/configs/kvm/patched.cfg
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "patched",
- "target": "linux/amd64",
- "kernel_obj": "/patched/obj",
- "image": "/patched/image",
- "vm": {
- "count": 9,
- "kernel": "/patched/kernel"
- }
-}
diff --git a/syz-cluster/workflow/configs/net/base.cfg b/syz-cluster/workflow/configs/net/base.cfg
deleted file mode 100644
index 2a5d57749..000000000
--- a/syz-cluster/workflow/configs/net/base.cfg
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "name": "base",
- "target": "linux/amd64",
- "kernel_obj": "/base/obj",
- "kernel_build_src": "/workdir",
- "image": "/base/image",
- "syzkaller": "/syzkaller",
- "workdir": "/workdir",
- "type": "qemu",
- "enable_syscalls": [
- "accept", "accept4", "bind", "close", "connect", "epoll_create",
- "epoll_create1", "epoll_ctl", "epoll_pwait", "epoll_wait",
- "getpeername", "getsockname", "getsockopt", "ioctl", "listen",
- "mmap", "poll", "ppoll", "pread64", "preadv", "pselect6",
- "pwrite64", "pwritev", "read", "readv", "recvfrom", "recvmmsg",
- "recvmsg", "select", "sendfile", "sendmmsg", "sendmsg", "sendto",
- "setsockopt", "shutdown", "socket", "socketpair", "splice",
- "vmsplice", "write", "writev", "tee", "bpf", "getpid",
- "getgid", "getuid", "gettid", "unshare", "pipe",
- "syz_emit_ethernet", "syz_extract_tcp_res",
- "syz_genetlink_get_family_id", "syz_init_net_socket",
- "mkdirat$cgroup*", "openat$cgroup*", "write$cgroup*",
- "clock_gettime", "bpf", "openat$tun", "openat$ppp",
- "syz_open_procfs$namespace", "syz_80211_*", "nanosleep",
- "openat$nci", "ioctl$IOCTL_GET_NCIDEV_IDX", "openat$rfkill",
- "openat$6lowpan*", "openat$pidfd", "openat$tcp*", "openat$vhost_vsock",
- "openat$ptp*", "ioctl$PTP*"
- ],
- "procs": 3,
- "sandbox": "none",
- "experimental": {"cover_edges": false},
- "vm": {
- "count": 3,
- "cmdline": "root=/dev/sda1",
- "kernel": "/base/kernel",
- "cpu": 2,
- "mem": 7168,
- "qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
- }
-}
diff --git a/syz-cluster/workflow/configs/net/patched.cfg b/syz-cluster/workflow/configs/net/patched.cfg
deleted file mode 100644
index 8b4027891..000000000
--- a/syz-cluster/workflow/configs/net/patched.cfg
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "patched",
- "target": "linux/amd64",
- "kernel_obj": "/patched/obj",
- "image": "/patched/image",
- "vm": {
- "count": 9,
- "kernel": "/patched/kernel"
- }
-}
diff --git a/syz-cluster/workflow/fuzz-step/Dockerfile b/syz-cluster/workflow/fuzz-step/Dockerfile
index 787d95e46..bc11e80da 100644
--- a/syz-cluster/workflow/fuzz-step/Dockerfile
+++ b/syz-cluster/workflow/fuzz-step/Dockerfile
@@ -33,6 +33,5 @@ RUN useradd --create-home syzkaller
COPY --from=fuzz-step-builder /build/bin/ /syzkaller/bin/
COPY --from=fuzz-step-builder /bin/fuzz-step /bin/fuzz-step
-COPY syz-cluster/workflow/configs/ /configs/
ENTRYPOINT ["/bin/fuzz-step"]
diff --git a/syz-cluster/workflow/fuzz-step/main.go b/syz-cluster/workflow/fuzz-step/main.go
index 227e3431d..5eb813e78 100644
--- a/syz-cluster/workflow/fuzz-step/main.go
+++ b/syz-cluster/workflow/fuzz-step/main.go
@@ -18,7 +18,7 @@ import (
"time"
"github.com/google/syzkaller/pkg/build"
- "github.com/google/syzkaller/pkg/config"
+ "github.com/google/syzkaller/pkg/db"
"github.com/google/syzkaller/pkg/log"
"github.com/google/syzkaller/pkg/manager"
"github.com/google/syzkaller/pkg/mgrconfig"
@@ -26,6 +26,7 @@ import (
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/syz-cluster/pkg/api"
"github.com/google/syzkaller/syz-cluster/pkg/app"
+ "github.com/google/syzkaller/syz-cluster/pkg/fuzzconfig"
"golang.org/x/sync/errgroup"
)
@@ -124,7 +125,7 @@ func run(baseCtx context.Context, config *api.FuzzConfig, client *api.Client,
const MB = 1000000
log.EnableLogCaching(100000, 10*MB)
- base, patched, err := loadConfigs("/configs", config.Config, true)
+ base, patched, err := generateConfigs(config)
if err != nil {
return fmt.Errorf("failed to load configs: %w", err)
}
@@ -139,12 +140,10 @@ func run(baseCtx context.Context, config *api.FuzzConfig, client *api.Client,
}
manager.PatchFocusAreas(patched, series.PatchBodies(), baseSymbols.Text, patchedSymbols.Text)
- if config.CorpusURL != "" {
- err := downloadCorpus(baseCtx, patched.Workdir, config.CorpusURL)
+ if len(config.CorpusURLs) > 0 {
+ err := prepareCorpus(baseCtx, patched.Workdir, config.CorpusURLs, patched.Target)
if err != nil {
- return fmt.Errorf("failed to download the corpus: %w", err)
- } else {
- log.Logf(0, "downloaded the corpus from %s", config.CorpusURL)
+ app.Errorf("failed to download the corpus: %v", err)
}
}
@@ -233,65 +232,70 @@ func run(baseCtx context.Context, config *api.FuzzConfig, client *api.Client,
return err
}
-func downloadCorpus(ctx context.Context, workdir, url string) error {
- out, err := os.Create(filepath.Join(workdir, "corpus.db"))
- if err != nil {
- return err
- }
- defer out.Close()
- req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
- if err != nil {
- return err
- }
- resp, err := (&http.Client{}).Do(req)
- if err != nil {
- return err
+func prepareCorpus(ctx context.Context, workdir string, urls []string, target *prog.Target) error {
+ corpusFile := filepath.Join(workdir, "corpus.db")
+ var otherFiles []string
+ for i, url := range urls {
+ log.Logf(0, "downloading corpus #%d: %q", i+1, url)
+ downloadTo := corpusFile
+ if i > 0 {
+ downloadTo = fmt.Sprintf("%s.%d", corpusFile, i)
+ otherFiles = append(otherFiles, downloadTo)
+ }
+ out, err := os.Create(corpusFile)
+ if err != nil {
+ return err
+ }
+ defer out.Close()
+ req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
+ if err != nil {
+ return err
+ }
+ resp, err := (&http.Client{}).Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ return fmt.Errorf("status is not 200: %s", resp.Status)
+ }
+ _, err = io.Copy(out, resp.Body)
+ if err != nil {
+ return err
+ }
}
- defer resp.Body.Close()
- if resp.StatusCode != http.StatusOK {
- return fmt.Errorf("status is not 200: %s", resp.Status)
+ if len(otherFiles) > 0 {
+ log.Logf(0, "merging corpuses")
+ skipped, err := db.Merge(corpusFile, otherFiles, target)
+ if err != nil {
+ return err
+ } else if len(skipped) > 0 {
+ log.Logf(0, "skipped %d entries", len(skipped))
+ }
}
- _, err = io.Copy(out, resp.Body)
- return err
+ return nil
}
-// To reduce duplication, patched configs are stored as a delta to their corresponding base.cfg version.
-// loadConfigs performs all the necessary merging and parsing and returns two ready to use configs.
-func loadConfigs(configFolder, configName string, complete bool) (*mgrconfig.Config, *mgrconfig.Config, error) {
- var baseRaw, deltaRaw json.RawMessage
- err := config.LoadFile(filepath.Join(configFolder, configName, "base.cfg"), &baseRaw)
+func generateConfigs(config *api.FuzzConfig) (*mgrconfig.Config, *mgrconfig.Config, error) {
+ base, err := fuzzconfig.GenerateBase(config)
if err != nil {
- return nil, nil, fmt.Errorf("failed to read the base config: %w", err)
+ return nil, nil, fmt.Errorf("failed to prepare base config: %w", err)
}
- err = config.LoadFile(filepath.Join(configFolder, configName, "patched.cfg"), &deltaRaw)
+ patched, err := fuzzconfig.GeneratePatched(config)
if err != nil {
- return nil, nil, fmt.Errorf("failed to read the patched config: %w", err)
+ return nil, nil, fmt.Errorf("failed to prepare patched config: %w", err)
}
- patchedRaw, err := config.MergeJSONs(baseRaw, deltaRaw)
+ base.Workdir = filepath.Join(*flagWorkdir, "base")
+ osutil.MkdirAll(base.Workdir)
+ patched.Workdir = filepath.Join(*flagWorkdir, "patched")
+ osutil.MkdirAll(patched.Workdir)
+ err = mgrconfig.Complete(base)
if err != nil {
- return nil, nil, fmt.Errorf("failed to merge the configs: %w", err)
+ return nil, nil, fmt.Errorf("failed to complete the base config: %w", err)
}
- base, err := mgrconfig.LoadPartialData(baseRaw)
+ err = mgrconfig.Complete(patched)
if err != nil {
- return nil, nil, fmt.Errorf("failed to parse the base config: %w", err)
- }
- patched, err := mgrconfig.LoadPartialData(patchedRaw)
- if err != nil {
- return nil, nil, fmt.Errorf("failed to parse the patched config: %w", err)
- }
- if complete {
- base.Workdir = filepath.Join(*flagWorkdir, "base")
- osutil.MkdirAll(base.Workdir)
- patched.Workdir = filepath.Join(*flagWorkdir, "patched")
- osutil.MkdirAll(patched.Workdir)
- err = mgrconfig.Complete(base)
- if err != nil {
- return nil, nil, fmt.Errorf("failed to complete the base config: %w", err)
- }
- err = mgrconfig.Complete(patched)
- if err != nil {
- return nil, nil, fmt.Errorf("failed to complete the patched config: %w", err)
- }
+ return nil, nil, fmt.Errorf("failed to complete the patched config: %w", err)
}
return base, patched, nil
}
diff --git a/syz-cluster/workflow/fuzz-step/main_test.go b/syz-cluster/workflow/fuzz-step/main_test.go
index 6f305a818..de10d507a 100644
--- a/syz-cluster/workflow/fuzz-step/main_test.go
+++ b/syz-cluster/workflow/fuzz-step/main_test.go
@@ -5,9 +5,7 @@ package main
import (
"encoding/json"
- "io/fs"
"os"
- "path/filepath"
"testing"
"github.com/google/syzkaller/pkg/build"
@@ -17,24 +15,6 @@ import (
"github.com/stretchr/testify/require"
)
-func TestConfigLoad(t *testing.T) {
- root := filepath.Join("..", "configs")
- filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
- if err != nil {
- return err
- }
- if !d.IsDir() || path == root {
- return nil
- }
- t.Logf("checking %v", path)
- _, _, err = loadConfigs(root, d.Name(), false)
- if err != nil {
- t.Fatalf("error proessing %q: %v", path, err)
- }
- return nil
- })
-}
-
func TestReadSectionHashes(t *testing.T) {
hashes := build.SectionHashes{
Text: map[string]string{"A": "1"},
diff --git a/syz-cluster/workflow/triage-step/main.go b/syz-cluster/workflow/triage-step/main.go
index 7e8061aef..37eddd5e8 100644
--- a/syz-cluster/workflow/triage-step/main.go
+++ b/syz-cluster/workflow/triage-step/main.go
@@ -85,14 +85,14 @@ func (triager *seriesTriager) GetVerdict(ctx context.Context, sessionID string)
SkipReason: "no suitable base kernel trees found",
}, nil
}
- fuzzConfig := triage.SelectFuzzConfig(series, treesResp.FuzzTargets)
- if fuzzConfig == nil {
+ fuzzConfigs := triage.MergeKernelFuzzConfigs(triage.SelectFuzzConfigs(series, treesResp.FuzzTargets))
+ if len(fuzzConfigs) == 0 {
return &api.TriageResult{
- SkipReason: "no suitable fuzz config found",
+ SkipReason: "no suitable fuzz configs found",
}, nil
}
ret := &api.TriageResult{}
- for _, campaign := range fuzzConfig.Campaigns {
+ for _, campaign := range fuzzConfigs {
fuzzTask, err := triager.prepareFuzzingTask(ctx, series, selectedTrees, campaign)
var skipErr *SkipTriageError
if errors.As(err, &skipErr) {
@@ -111,7 +111,7 @@ func (triager *seriesTriager) GetVerdict(ctx context.Context, sessionID string)
}
func (triager *seriesTriager) prepareFuzzingTask(ctx context.Context, series *api.Series, trees []*api.Tree,
- target *api.KernelFuzzConfig) (*api.FuzzTask, error) {
+ target *triage.MergedFuzzConfig) (*api.FuzzTask, error) {
var skipErr error
for _, tree := range trees {
triager.Log("considering tree %q", tree.Name)
@@ -151,7 +151,7 @@ func (triager *seriesTriager) prepareFuzzingTask(ctx context.Context, series *ap
fuzz := &api.FuzzTask{
Base: base,
Patched: base,
- FuzzConfig: target.FuzzConfig,
+ FuzzConfig: *target.FuzzConfig,
}
fuzz.Patched.SeriesID = series.ID
return fuzz, nil