From 06ece2ca663d0565d9e4cd932c4c2d86767a5396 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 12 Jun 2018 14:05:02 +0200 Subject: pkg/host: rework host feature detection/setup Currently host feature detection/setup code is spread across platform-independent fuzzer code, pkg/host, pkg/ipc and executor. Move this all into pkg/host and show readable info about features on manager start. Fixes #46 --- pkg/host/host.go | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'pkg/host/host.go') diff --git a/pkg/host/host.go b/pkg/host/host.go index c8f786e5a..d4f4d71a8 100644 --- a/pkg/host/host.go +++ b/pkg/host/host.go @@ -26,3 +26,82 @@ func DetectSupportedSyscalls(target *prog.Target, sandbox string) ( } return supported, unsupported, nil } + +const ( + FeatureCoverage = iota + FeatureComparisons + FeatureSandboxSetuid + FeatureSandboxNamespace + FeatureFaultInjection + FeatureLeakChecking + FeatureNetworkInjection + numFeatures +) + +type Feature struct { + Name string + Enabled bool + Reason string +} + +type Features [numFeatures]Feature + +var checkFeature [numFeatures]func() string +var setupFeature [numFeatures]func() error +var callbFeature [numFeatures]func() + +func unconditionallyEnabled() string { return "" } + +// Check detects features supported on the host. +// Empty string for a feature means the feature is supported, +// otherwise the string contains the reason why the feature is not supported. +func Check() (*Features, error) { + const unsupported = "support is not implemented in syzkaller" + res := &Features{ + FeatureCoverage: {Name: "code coverage", Reason: unsupported}, + FeatureComparisons: {Name: "comparison tracing", Reason: unsupported}, + FeatureSandboxSetuid: {Name: "setuid sandbox", Reason: unsupported}, + FeatureSandboxNamespace: {Name: "namespace sandbox", Reason: unsupported}, + FeatureFaultInjection: {Name: "fault injection", Reason: unsupported}, + FeatureLeakChecking: {Name: "leak checking", Reason: unsupported}, + FeatureNetworkInjection: {Name: "net packed injection", Reason: unsupported}, + } + for n, check := range checkFeature { + if check == nil { + continue + } + if reason := check(); reason == "" { + res[n].Enabled = true + res[n].Reason = "enabled" + } else { + res[n].Reason = reason + } + } + return res, nil +} + +// Setup enables and does any one-time setup for the requested features on the host. +// Note: this can be called multiple times and must be idempotent. +func Setup(features *Features) (func(), error) { + var callback func() + for n, setup := range setupFeature { + if setup == nil || !features[n].Enabled { + continue + } + if err := setup(); err != nil { + return nil, err + } + cb := callbFeature[n] + if cb != nil { + prev := callback + callback = func() { + cb() + if prev != nil { + prev() + } + } + + } + } + return callback, nil +} -- cgit mrf-deployment