From 3f94021ec61c81270e948abb0efe7da66ace3d5a Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 6 May 2024 13:10:47 +0200 Subject: pkg/repro, pkg/ipc: use flatrpc.Feature Start switching from host.Features to flatrpc.Features. This change is supposed to be a no-op, just to reduce future diffs that will change how we obtain features. --- pkg/host/features.go | 63 ++++++++++++++++++++++++++++++++++++++++++ pkg/ipc/ipc.go | 20 +++++++------- pkg/repro/repro.go | 62 ++++++++++++++++++++--------------------- pkg/repro/repro_test.go | 3 +- pkg/runtest/run.go | 18 ++++++------ pkg/runtest/run_test.go | 2 +- syz-fuzzer/testing.go | 2 +- syz-manager/hub.go | 4 +-- syz-manager/manager.go | 21 +++++++------- syz-manager/rpc.go | 8 ++++-- tools/syz-execprog/execprog.go | 2 +- tools/syz-repro/repro.go | 3 +- tools/syz-runtest/runtest.go | 2 +- 13 files changed, 138 insertions(+), 72 deletions(-) diff --git a/pkg/host/features.go b/pkg/host/features.go index 80f083a21..8a8629084 100644 --- a/pkg/host/features.go +++ b/pkg/host/features.go @@ -9,6 +9,7 @@ import ( "time" "github.com/google/syzkaller/pkg/csource" + "github.com/google/syzkaller/pkg/flatrpc" "github.com/google/syzkaller/pkg/log" "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/prog" @@ -50,6 +51,68 @@ func (features *Features) Supported() *Features { return features } +func (features *Features) ToFlatRPC() flatrpc.Feature { + var result flatrpc.Feature + if features[FeatureCoverage].Enabled { + result |= flatrpc.FeatureCoverage + } + if features[FeatureComparisons].Enabled { + result |= flatrpc.FeatureComparisons + } + if features[FeatureExtraCoverage].Enabled { + result |= flatrpc.FeatureExtraCoverage + } + if features[FeatureDelayKcovMmap].Enabled { + result |= flatrpc.FeatureDelayKcovMmap + } + if features[FeatureSandboxSetuid].Enabled { + result |= flatrpc.FeatureSandboxSetuid + } + if features[FeatureSandboxNamespace].Enabled { + result |= flatrpc.FeatureSandboxNamespace + } + if features[FeatureSandboxAndroid].Enabled { + result |= flatrpc.FeatureSandboxAndroid + } + if features[FeatureFault].Enabled { + result |= flatrpc.FeatureFault + } + if features[FeatureLeak].Enabled { + result |= flatrpc.FeatureLeak + } + if features[FeatureNetInjection].Enabled { + result |= flatrpc.FeatureNetInjection + } + if features[FeatureNetDevices].Enabled { + result |= flatrpc.FeatureNetDevices + } + if features[FeatureKCSAN].Enabled { + result |= flatrpc.FeatureKCSAN + } + if features[FeatureDevlinkPCI].Enabled { + result |= flatrpc.FeatureDevlinkPCI + } + if features[FeatureNicVF].Enabled { + result |= flatrpc.FeatureNicVF + } + if features[FeatureUSBEmulation].Enabled { + result |= flatrpc.FeatureUSBEmulation + } + if features[FeatureVhciInjection].Enabled { + result |= flatrpc.FeatureVhciInjection + } + if features[FeatureWifiEmulation].Enabled { + result |= flatrpc.FeatureWifiEmulation + } + if features[Feature802154Emulation].Enabled { + result |= flatrpc.FeatureLRWPANEmulation + } + if features[FeatureSwap].Enabled { + result |= flatrpc.FeatureSwap + } + return result +} + var checkFeature [numFeatures]func() string func unconditionallyEnabled() string { return "" } diff --git a/pkg/ipc/ipc.go b/pkg/ipc/ipc.go index 6185a6181..79b2acc18 100644 --- a/pkg/ipc/ipc.go +++ b/pkg/ipc/ipc.go @@ -18,7 +18,7 @@ import ( "github.com/google/syzkaller/pkg/cover" "github.com/google/syzkaller/pkg/csource" - "github.com/google/syzkaller/pkg/host" + "github.com/google/syzkaller/pkg/flatrpc" "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/pkg/signal" "github.com/google/syzkaller/prog" @@ -158,7 +158,7 @@ func FlagsToSandbox(flags EnvFlags) string { } // nolint: gocyclo -func FeaturesToFlags(feat *host.Features, manual csource.Features) EnvFlags { +func FeaturesToFlags(features flatrpc.Feature, manual csource.Features) EnvFlags { var flags EnvFlags if manual == nil || manual["net_reset"].Enabled { flags |= FlagEnableNetReset @@ -169,28 +169,28 @@ func FeaturesToFlags(feat *host.Features, manual csource.Features) EnvFlags { if manual == nil || manual["close_fds"].Enabled { flags |= FlagEnableCloseFds } - if feat[host.FeatureExtraCoverage].Enabled { + if features&flatrpc.FeatureExtraCoverage != 0 { flags |= FlagExtraCover } - if feat[host.FeatureDelayKcovMmap].Enabled { + if features&flatrpc.FeatureDelayKcovMmap != 0 { flags |= FlagDelayKcovMmap } - if feat[host.FeatureNetInjection].Enabled && (manual == nil || manual["tun"].Enabled) { + if features&flatrpc.FeatureNetInjection != 0 && (manual == nil || manual["tun"].Enabled) { flags |= FlagEnableTun } - if feat[host.FeatureNetDevices].Enabled && (manual == nil || manual["net_dev"].Enabled) { + if features&flatrpc.FeatureNetDevices != 0 && (manual == nil || manual["net_dev"].Enabled) { flags |= FlagEnableNetDev } - if feat[host.FeatureDevlinkPCI].Enabled && (manual == nil || manual["devlink_pci"].Enabled) { + if features&flatrpc.FeatureDevlinkPCI != 0 && (manual == nil || manual["devlink_pci"].Enabled) { flags |= FlagEnableDevlinkPCI } - if feat[host.FeatureNicVF].Enabled && (manual == nil || manual["nic_vf"].Enabled) { + if features&flatrpc.FeatureNicVF != 0 && (manual == nil || manual["nic_vf"].Enabled) { flags |= FlagEnableNicVF } - if feat[host.FeatureVhciInjection].Enabled && (manual == nil || manual["vhci"].Enabled) { + if features&flatrpc.FeatureVhciInjection != 0 && (manual == nil || manual["vhci"].Enabled) { flags |= FlagEnableVhciInjection } - if feat[host.FeatureWifiEmulation].Enabled && (manual == nil || manual["wifi"].Enabled) { + if features&flatrpc.FeatureWifiEmulation != 0 && (manual == nil || manual["wifi"].Enabled) { flags |= FlagEnableWifi } return flags diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go index 21c15fc66..b14b537f8 100644 --- a/pkg/repro/repro.go +++ b/pkg/repro/repro.go @@ -13,7 +13,7 @@ import ( "github.com/google/syzkaller/pkg/bisect/minimize" "github.com/google/syzkaller/pkg/csource" - "github.com/google/syzkaller/pkg/host" + "github.com/google/syzkaller/pkg/flatrpc" "github.com/google/syzkaller/pkg/instance" "github.com/google/syzkaller/pkg/log" "github.com/google/syzkaller/pkg/mgrconfig" @@ -74,7 +74,7 @@ type execInterface interface { var ErrNoPrograms = errors.New("crash log does not contain any programs") -func Run(crashLog []byte, cfg *mgrconfig.Config, features *host.Features, reporter *report.Reporter, +func Run(crashLog []byte, cfg *mgrconfig.Config, features flatrpc.Feature, reporter *report.Reporter, vmPool *vm.Pool, vmIndexes []int) (*Result, *Stats, error) { ctx, err := prepareCtx(crashLog, cfg, features, reporter, len(vmIndexes)) if err != nil { @@ -95,7 +95,7 @@ func Run(crashLog []byte, cfg *mgrconfig.Config, features *host.Features, report return ctx.run() } -func prepareCtx(crashLog []byte, cfg *mgrconfig.Config, features *host.Features, reporter *report.Reporter, +func prepareCtx(crashLog []byte, cfg *mgrconfig.Config, features flatrpc.Feature, reporter *report.Reporter, VMs int) (*context, error) { if VMs == 0 { return nil, fmt.Errorf("no VMs provided") @@ -178,40 +178,38 @@ func (ctx *context) run() (*Result, *Stats, error) { return res, ctx.stats, nil } -func createStartOptions(cfg *mgrconfig.Config, features *host.Features, +func createStartOptions(cfg *mgrconfig.Config, features flatrpc.Feature, crashType crash.Type) csource.Options { opts := csource.DefaultOpts(cfg) if crashType == crash.MemoryLeak { opts.Leak = true } - if features != nil { - if !features[host.FeatureNetInjection].Enabled { - opts.NetInjection = false - } - if !features[host.FeatureNetDevices].Enabled { - opts.NetDevices = false - } - if !features[host.FeatureDevlinkPCI].Enabled { - opts.DevlinkPCI = false - } - if !features[host.FeatureNicVF].Enabled { - opts.NicVF = false - } - if !features[host.FeatureUSBEmulation].Enabled { - opts.USB = false - } - if !features[host.FeatureVhciInjection].Enabled { - opts.VhciInjection = false - } - if !features[host.FeatureWifiEmulation].Enabled { - opts.Wifi = false - } - if !features[host.Feature802154Emulation].Enabled { - opts.IEEE802154 = false - } - if !features[host.FeatureSwap].Enabled { - opts.Swap = false - } + if features&flatrpc.FeatureNetInjection == 0 { + opts.NetInjection = false + } + if features&flatrpc.FeatureNetDevices == 0 { + opts.NetDevices = false + } + if features&flatrpc.FeatureDevlinkPCI == 0 { + opts.DevlinkPCI = false + } + if features&flatrpc.FeatureNicVF == 0 { + opts.NicVF = false + } + if features&flatrpc.FeatureUSBEmulation == 0 { + opts.USB = false + } + if features&flatrpc.FeatureVhciInjection == 0 { + opts.VhciInjection = false + } + if features&flatrpc.FeatureWifiEmulation == 0 { + opts.Wifi = false + } + if features&flatrpc.FeatureLRWPANEmulation == 0 { + opts.IEEE802154 = false + } + if features&flatrpc.FeatureSwap == 0 { + opts.Swap = false } return opts } diff --git a/pkg/repro/repro_test.go b/pkg/repro/repro_test.go index 368ab3dff..744064c22 100644 --- a/pkg/repro/repro_test.go +++ b/pkg/repro/repro_test.go @@ -13,6 +13,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/syzkaller/pkg/csource" + "github.com/google/syzkaller/pkg/flatrpc" "github.com/google/syzkaller/pkg/instance" "github.com/google/syzkaller/pkg/mgrconfig" "github.com/google/syzkaller/pkg/report" @@ -158,7 +159,7 @@ func prepareTestCtx(t *testing.T, log string) *context { if err != nil { t.Fatal(err) } - ctx, err := prepareCtx([]byte(log), mgrConfig, nil, reporter, 3) + ctx, err := prepareCtx([]byte(log), mgrConfig, flatrpc.AllFeatures, reporter, 3) if err != nil { t.Fatal(err) } diff --git a/pkg/runtest/run.go b/pkg/runtest/run.go index 796fb6040..d32e9f8d3 100644 --- a/pkg/runtest/run.go +++ b/pkg/runtest/run.go @@ -23,7 +23,7 @@ import ( "strings" "github.com/google/syzkaller/pkg/csource" - "github.com/google/syzkaller/pkg/host" + "github.com/google/syzkaller/pkg/flatrpc" "github.com/google/syzkaller/pkg/ipc" "github.com/google/syzkaller/prog" "github.com/google/syzkaller/sys/targets" @@ -50,7 +50,7 @@ type RunRequest struct { type Context struct { Dir string Target *prog.Target - Features *host.Features + Features flatrpc.Feature EnabledCalls map[string]map[*prog.Syscall]bool Requests chan *RunRequest LogFunc func(text string) @@ -164,7 +164,7 @@ func (ctx *Context) Run() error { func (ctx *Context) generatePrograms(progs chan *RunRequest) error { cover := []bool{false} - if ctx.Features[host.FeatureCoverage].Enabled { + if ctx.Features&flatrpc.FeatureCoverage != 0 { cover = append(cover, true) } var sandboxes []string @@ -448,22 +448,22 @@ func (ctx *Context) createCTest(p *prog.Prog, sandbox string, threaded bool, tim HandleSegv: true, Cgroups: p.Target.OS == targets.Linux && sandbox != "", Trace: true, - Swap: ctx.Features[host.FeatureSwap].Enabled, + Swap: ctx.Features&flatrpc.FeatureSwap != 0, } if sandbox != "" { - if ctx.Features[host.FeatureNetInjection].Enabled { + if ctx.Features&flatrpc.FeatureNetInjection != 0 { opts.NetInjection = true } - if ctx.Features[host.FeatureNetDevices].Enabled { + if ctx.Features&flatrpc.FeatureNetDevices != 0 { opts.NetDevices = true } - if ctx.Features[host.FeatureVhciInjection].Enabled { + if ctx.Features&flatrpc.FeatureVhciInjection != 0 { opts.VhciInjection = true } - if ctx.Features[host.FeatureWifiEmulation].Enabled { + if ctx.Features&flatrpc.FeatureWifiEmulation != 0 { opts.Wifi = true } - if ctx.Features[host.Feature802154Emulation].Enabled { + if ctx.Features&flatrpc.FeatureLRWPANEmulation != 0 { opts.IEEE802154 = true } } diff --git a/pkg/runtest/run_test.go b/pkg/runtest/run_test.go index 6377876d6..c06136078 100644 --- a/pkg/runtest/run_test.go +++ b/pkg/runtest/run_test.go @@ -93,7 +93,7 @@ func test(t *testing.T, sysTarget *targets.Target) { Dir: filepath.Join("..", "..", "sys", target.OS, targets.TestOS), Target: target, Tests: *flagFilter, - Features: features, + Features: features.ToFlatRPC(), EnabledCalls: enabledCalls, Requests: requests, LogFunc: func(text string) { diff --git a/syz-fuzzer/testing.go b/syz-fuzzer/testing.go index bd2eb33e1..925504b7e 100644 --- a/syz-fuzzer/testing.go +++ b/syz-fuzzer/testing.go @@ -88,7 +88,7 @@ func checkMachine(args *checkArgs) (*rpctype.CheckArgs, error) { args.ipcExecOpts.EnvFlags&ipc.FlagSandboxAndroid != 0 { return nil, fmt.Errorf("sandbox=android is not supported (%v)", feat.Reason) } - args.ipcExecOpts.EnvFlags |= ipc.FeaturesToFlags(features, nil) + args.ipcExecOpts.EnvFlags |= ipc.FeaturesToFlags(features.ToFlatRPC(), nil) if err := checkSimpleProgram(args, features); err != nil { return nil, err } diff --git a/syz-manager/hub.go b/syz-manager/hub.go index dd0cbbcdb..fc9662bb0 100644 --- a/syz-manager/hub.go +++ b/syz-manager/hub.go @@ -9,9 +9,9 @@ import ( "time" "github.com/google/syzkaller/pkg/auth" + "github.com/google/syzkaller/pkg/flatrpc" "github.com/google/syzkaller/pkg/fuzzer" "github.com/google/syzkaller/pkg/hash" - "github.com/google/syzkaller/pkg/host" "github.com/google/syzkaller/pkg/log" "github.com/google/syzkaller/pkg/mgrconfig" "github.com/google/syzkaller/pkg/report" @@ -44,7 +44,7 @@ func (mgr *Manager) hubSyncLoop(keyGet keyGetter) { target: mgr.target, domain: mgr.cfg.TargetOS + "/" + mgr.cfg.HubDomain, enabledCalls: mgr.targetEnabledSyscalls, - leak: mgr.checkFeatures[host.FeatureLeak].Enabled, + leak: mgr.enabledFeatures&flatrpc.FeatureLeak != 0, fresh: mgr.fresh, hubReproQueue: mgr.externalReproQueue, keyGet: keyGet, diff --git a/syz-manager/manager.go b/syz-manager/manager.go index f5437f853..c379bd3ee 100644 --- a/syz-manager/manager.go +++ b/syz-manager/manager.go @@ -24,10 +24,10 @@ import ( "github.com/google/syzkaller/pkg/corpus" "github.com/google/syzkaller/pkg/csource" "github.com/google/syzkaller/pkg/db" + "github.com/google/syzkaller/pkg/flatrpc" "github.com/google/syzkaller/pkg/fuzzer" "github.com/google/syzkaller/pkg/gce" "github.com/google/syzkaller/pkg/hash" - "github.com/google/syzkaller/pkg/host" "github.com/google/syzkaller/pkg/instance" "github.com/google/syzkaller/pkg/log" "github.com/google/syzkaller/pkg/mgrconfig" @@ -63,7 +63,8 @@ type Manager struct { firstConnect atomic.Int64 // unix time, or 0 if not connected crashTypes map[string]bool vmStop chan bool - checkFeatures *host.Features + enabledFeatures flatrpc.Feature + checkDone bool fresh bool expertMode bool nextInstanceID atomic.Uint64 @@ -459,7 +460,7 @@ func reportReproError(err error) { } func (mgr *Manager) runRepro(crash *Crash, vmIndexes []int, putInstances func(...int)) *ReproResult { - res, stats, err := repro.Run(crash.Output, mgr.cfg, mgr.checkFeatures, mgr.reporter, mgr.vmPool, vmIndexes) + res, stats, err := repro.Run(crash.Output, mgr.cfg, mgr.enabledFeatures, mgr.reporter, mgr.vmPool, vmIndexes) ret := &ReproResult{ instances: vmIndexes, report0: crash.Report, @@ -983,7 +984,7 @@ func (mgr *Manager) needRepro(crash *Crash) bool { if crash.fromHub || crash.fromDashboard { return true } - if mgr.checkFeatures == nil || (mgr.checkFeatures[host.FeatureLeak].Enabled && + if !mgr.checkDone || (mgr.enabledFeatures&flatrpc.FeatureLeak != 0 && crash.Type != crash_pkg.MemoryLeak) { // Leak checking is very slow, don't bother reproducing other crashes on leak instance. return false @@ -1337,14 +1338,14 @@ func (mgr *Manager) currentBugFrames() BugFrames { return frames } -func (mgr *Manager) machineChecked(features *host.Features, enabledSyscalls map[*prog.Syscall]bool) { +func (mgr *Manager) machineChecked(features flatrpc.Feature, enabledSyscalls map[*prog.Syscall]bool) { mgr.mu.Lock() defer mgr.mu.Unlock() - if mgr.checkFeatures != nil { + if mgr.checkDone { panic("machineChecked() called twice") } - - mgr.checkFeatures = features + mgr.checkDone = true + mgr.enabledFeatures = features mgr.targetEnabledSyscalls = enabledSyscalls statSyscalls := stats.Create("syscalls", "Number of enabled syscalls", stats.Simple, stats.NoGraph, stats.Link("/syscalls")) @@ -1354,8 +1355,8 @@ func (mgr *Manager) machineChecked(features *host.Features, enabledSyscalls map[ fuzzerObj := fuzzer.NewFuzzer(context.Background(), &fuzzer.Config{ Corpus: mgr.corpus, Coverage: mgr.cfg.Cover, - FaultInjection: features[host.FeatureFault].Enabled, - Comparisons: features[host.FeatureComparisons].Enabled, + FaultInjection: features&flatrpc.FeatureFault != 0, + Comparisons: features&flatrpc.FeatureComparisons != 0, Collide: true, EnabledCalls: enabledSyscalls, NoMutateCalls: mgr.cfg.NoMutateCalls, diff --git a/syz-manager/rpc.go b/syz-manager/rpc.go index a27485388..7323d5e38 100644 --- a/syz-manager/rpc.go +++ b/syz-manager/rpc.go @@ -43,6 +43,7 @@ type RPCServer struct { needCheckResults int checkFailures int checkFeatures *host.Features + enabledFeatures flatrpc.Feature modules []cover.KernelModule canonicalModules *cover.Canonicalizer execCoverFilter map[uint32]uint32 @@ -98,7 +99,7 @@ type BugFrames struct { // RPCManagerView restricts interface between RPCServer and Manager. type RPCManagerView interface { currentBugFrames() BugFrames - machineChecked(features *host.Features, enabledSyscalls map[*prog.Syscall]bool) + machineChecked(features flatrpc.Feature, enabledSyscalls map[*prog.Syscall]bool) getFuzzer() *fuzzer.Fuzzer } @@ -206,6 +207,7 @@ func (serv *RPCServer) Check(a *rpctype.CheckArgs, r *rpctype.CheckRes) error { if serv.checkFeatures == nil { serv.checkFeatures = a.Features + serv.enabledFeatures = a.Features.ToFlatRPC() serv.checkFilesInfo = a.Files serv.modules = modules serv.target.UpdateGlobs(a.Globs) @@ -287,7 +289,7 @@ func (serv *RPCServer) finishCheck() error { if len(enabledCalls) == 0 { log.Fatalf("all system calls are disabled") } - serv.mgr.machineChecked(serv.checkFeatures, enabledCalls) + serv.mgr.machineChecked(serv.enabledFeatures, enabledCalls) return nil } @@ -576,7 +578,7 @@ func (serv *RPCServer) newRequest(runner *Runner, req *fuzzer.Request) (rpctype. } func (serv *RPCServer) createExecOpts(req *fuzzer.Request) ipc.ExecOpts { - env := ipc.FeaturesToFlags(serv.checkFeatures, nil) + env := ipc.FeaturesToFlags(serv.enabledFeatures, nil) if *flagDebug { env |= ipc.FlagDebug } diff --git a/tools/syz-execprog/execprog.go b/tools/syz-execprog/execprog.go index 6c3314721..7f328e31a 100644 --- a/tools/syz-execprog/execprog.go +++ b/tools/syz-execprog/execprog.go @@ -418,7 +418,7 @@ func createConfig(target *prog.Target, features *host.Features, featuresFlags cs } execOpts.ExecFlags |= ipc.FlagCollectComps } - execOpts.EnvFlags |= ipc.FeaturesToFlags(features, featuresFlags) + execOpts.EnvFlags |= ipc.FeaturesToFlags(features.ToFlatRPC(), featuresFlags) return config, execOpts } diff --git a/tools/syz-repro/repro.go b/tools/syz-repro/repro.go index aa4e473c0..1c5d18cb9 100644 --- a/tools/syz-repro/repro.go +++ b/tools/syz-repro/repro.go @@ -10,6 +10,7 @@ import ( "path/filepath" "github.com/google/syzkaller/pkg/csource" + "github.com/google/syzkaller/pkg/flatrpc" "github.com/google/syzkaller/pkg/log" "github.com/google/syzkaller/pkg/mgrconfig" "github.com/google/syzkaller/pkg/osutil" @@ -64,7 +65,7 @@ func main() { } osutil.HandleInterrupts(vm.Shutdown) - res, stats, err := repro.Run(data, cfg, nil, reporter, vmPool, vmIndexes) + res, stats, err := repro.Run(data, cfg, flatrpc.AllFeatures, reporter, vmPool, vmIndexes) if err != nil { log.Logf(0, "reproduction failed: %v", err) } diff --git a/tools/syz-runtest/runtest.go b/tools/syz-runtest/runtest.go index fa3dbaa49..1203abbb5 100644 --- a/tools/syz-runtest/runtest.go +++ b/tools/syz-runtest/runtest.go @@ -125,7 +125,7 @@ func main() { ctx := &runtest.Context{ Dir: filepath.Join(cfg.Syzkaller, "sys", cfg.Target.OS, "test"), Target: cfg.Target, - Features: checkResult.Features, + Features: checkResult.Features.ToFlatRPC(), EnabledCalls: enabledCalls, Requests: mgr.requests, LogFunc: func(text string) { fmt.Println(text) }, -- cgit mrf-deployment