diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2025-09-18 17:36:53 +0200 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2025-10-07 15:25:13 +0000 |
| commit | 99ed12e158687b7aba55eac142d6bad3f147d029 (patch) | |
| tree | a9809d7c5d60f45b805e0346a9a543ba0651a9e1 | |
| parent | 790f0ffe2224829b20e4dc6556c090c503e1d161 (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.
39 files changed, 1846 insertions, 406 deletions
diff --git a/pkg/db/db.go b/pkg/db/db.go index 034d1bf67..3007a8774 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -346,3 +346,42 @@ func ReadCorpus(filename string, target *prog.Target) (progs []*prog.Prog, err e } return progs, nil } + +type DeserializeFailure struct { + File string + Err error +} + +func Merge(into string, other []string, target *prog.Target) ([]DeserializeFailure, error) { + dstDB, err := Open(into, false) + if err != nil { + return nil, fmt.Errorf("failed to open database: %w", err) + } + var failed []DeserializeFailure + for _, add := range other { + addDB, err := Open(add, false) + if err == nil { + // It's a DB file. + for key, rec := range addDB.Records { + dstDB.Save(key, rec.Val, rec.Seq) + } + continue + } + if target == nil { + // We were not given a target, so we cannot parse it as a seed file. + return nil, fmt.Errorf("failed to open db %v: %w", add, err) + } + data, err := os.ReadFile(add) + if err != nil { + return nil, err + } + if _, err := target.Deserialize(data, prog.NonStrict); err != nil { + failed = append(failed, DeserializeFailure{add, err}) + } + dstDB.Save(hash.String(data), data, 0) + } + if err := dstDB.Flush(); err != nil { + return nil, fmt.Errorf("failed to save db: %w", err) + } + return failed, nil +} 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 diff --git a/tools/syz-db/syz-db.go b/tools/syz-db/syz-db.go index 3cec95097..65d1c5ba8 100644 --- a/tools/syz-db/syz-db.go +++ b/tools/syz-db/syz-db.go @@ -169,30 +169,15 @@ func unpack(file, dir string) { } func merge(file string, adds []string, target *prog.Target) { - dstDB, err := db.Open(file, false) + failures, err := db.Merge(file, adds, target) if err != nil { - tool.Failf("failed to open database: %v", err) + tool.Failf("%s", err) } - for _, add := range adds { - if addDB, err := db.Open(add, false); err == nil { - for key, rec := range addDB.Records { - dstDB.Save(key, rec.Val, rec.Seq) - } - continue - } else if target == nil { - tool.Failf("failed to open db %v: %v", add, err) - } - data, err := os.ReadFile(add) - if err != nil { - tool.Fail(err) - } - if _, err := target.Deserialize(data, prog.NonStrict); err != nil { - tool.Failf("failed to deserialize %v: %v", add, err) + if len(failures) > 0 { + for _, fail := range failures { + fmt.Printf("failed to deserialize a record from %s: %s\n", fail.File, fail.Err) } - dstDB.Save(hash.String(data), data, 0) - } - if err := dstDB.Flush(); err != nil { - tool.Failf("failed to save db: %v", err) + tool.Failf("there have been deserialization errors") } } |
