diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-04-29 07:55:46 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-04-29 14:53:56 +0000 |
| commit | ee51f7ac1dd0df7131343d099fd0b87aac42f360 (patch) | |
| tree | 4380123b153453dc87b720df601dc8478bfeefa3 | |
| parent | ad452794ee865e84d6bf40479e327aa9d07dec60 (diff) | |
syz-manager: print better message about disabled syscalls
Print better message and print it when verbosity >= 1.
This will allow to easier diff any changes in enabled
syscalls caused by future code changes.
| -rw-r--r-- | pkg/host/syscalls.go | 21 | ||||
| -rw-r--r-- | prog/resources.go | 7 | ||||
| -rw-r--r-- | prog/resources_test.go | 3 | ||||
| -rw-r--r-- | syz-fuzzer/testing.go | 11 | ||||
| -rw-r--r-- | syz-manager/rpc.go | 68 |
5 files changed, 60 insertions, 50 deletions
diff --git a/pkg/host/syscalls.go b/pkg/host/syscalls.go index cd49ded51..3068cec2b 100644 --- a/pkg/host/syscalls.go +++ b/pkg/host/syscalls.go @@ -15,29 +15,20 @@ func DetectSupportedSyscalls(target *prog.Target, sandbox string, enabled map[*p log.Logf(1, "detecting supported syscalls") supported := make(map[*prog.Syscall]bool) unsupported := make(map[*prog.Syscall]string) - const disabledAttribute = "has disabled attribute in descriptions" // These do not have own host and parasitize on some other OS. if noHostChecks(target) { for _, c := range target.Syscalls { - if c.Attrs.Disabled { - unsupported[c] = disabledAttribute - } else { - supported[c] = true + if c.Attrs.Disabled || !enabled[c] { + continue } + supported[c] = true } } else { for _, c := range target.Syscalls { - ok, reason := false, "" - switch { - case c.Attrs.Disabled: - ok = false - reason = disabledAttribute - case !enabled[c]: - ok = false - reason = "not in set of enabled calls" - default: - ok, reason = isSupported(c, target, sandbox) + if c.Attrs.Disabled || !enabled[c] { + continue } + ok, reason := isSupported(c, target, sandbox) if ok { supported[c] = true } else { diff --git a/prog/resources.go b/prog/resources.go index d739b528e..c200b2c5c 100644 --- a/prog/resources.go +++ b/prog/resources.go @@ -211,11 +211,12 @@ func (target *Target) TransitivelyEnabledCalls(enabled map[*Syscall]bool) (map[* for _, ctor := range target.calcResourceCtors(res, true) { names = append(names, ctor.Call.Name) } + if len(names) > 5 { + names = append(names[:3], "...") + } ctors[res.Name] = names } - disabled[c] = fmt.Sprintf("no syscalls can create resource %v,"+ - " enable some syscalls that can create it %v", - res.Name, ctors[res.Name]) + disabled[c] = fmt.Sprintf("%v %v", res.Name, ctors[res.Name]) break } } diff --git a/prog/resources_test.go b/prog/resources_test.go index aa43580a1..180cfe1d6 100644 --- a/prog/resources_test.go +++ b/prog/resources_test.go @@ -92,8 +92,7 @@ func TestTransitivelyEnabledCallsLinux(t *testing.T) { t.Fatalf("disabled %v syscalls, want 8", len(disabled)) } for c, reason := range disabled { - if !strings.Contains(reason, "no syscalls can create resource fd_epoll,"+ - " enable some syscalls that can create it [epoll_create epoll_create1]") { + if !strings.Contains(reason, "fd_epoll [epoll_create epoll_create1]") { t.Fatalf("%v: wrong disable reason: %v", c.Name, reason) } } diff --git a/syz-fuzzer/testing.go b/syz-fuzzer/testing.go index ceecaf76a..a8783104e 100644 --- a/syz-fuzzer/testing.go +++ b/syz-fuzzer/testing.go @@ -298,17 +298,6 @@ func buildCallList(target *prog.Target, enabledCalls []int, sandbox string) ( delete(calls, c) } } - _, unsupported = target.TransitivelyEnabledCalls(calls) - for c := range calls { - if reason, ok := unsupported[c]; ok { - log.Logf(1, "transitively unsupported: %v(): %v", c.Name, reason) - disabled = append(disabled, rpctype.SyscallReason{ - ID: c.ID, - Reason: reason, - }) - delete(calls, c) - } - } for c := range calls { enabled = append(enabled, c.ID) } diff --git a/syz-manager/rpc.go b/syz-manager/rpc.go index 07533e078..183cda24e 100644 --- a/syz-manager/rpc.go +++ b/syz-manager/rpc.go @@ -7,6 +7,8 @@ import ( "bytes" "fmt" "net" + "sort" + "strings" "sync" "time" @@ -189,23 +191,59 @@ func (serv *RPCServer) Check(a *rpctype.CheckArgs, r *rpctype.CheckRes) error { func (serv *RPCServer) check(a *rpctype.CheckArgs, modules []host.KernelModule) error { // Note: need to print disbled syscalls before failing due to an error. // This helps to debug "all system calls are disabled". - if len(serv.cfg.EnabledSyscalls) != 0 && len(a.DisabledCalls[serv.cfg.Sandbox]) != 0 { - disabled := make(map[string]string) - for _, dc := range a.DisabledCalls[serv.cfg.Sandbox] { - disabled[serv.cfg.Target.Syscalls[dc.ID].Name] = dc.Reason + enabledCalls := make(map[*prog.Syscall]bool) + for _, call := range a.EnabledCalls[serv.cfg.Sandbox] { + enabledCalls[serv.cfg.Target.Syscalls[call]] = true + } + disabledCalls := make(map[*prog.Syscall]string) + for _, dc := range a.DisabledCalls[serv.cfg.Sandbox] { + disabledCalls[serv.cfg.Target.Syscalls[dc.ID]] = dc.Reason + } + enabledCalls, transitivelyDisabled := serv.target.TransitivelyEnabledCalls(enabledCalls) + buf := new(bytes.Buffer) + if len(serv.cfg.EnabledSyscalls) != 0 || log.V(1) { + if len(disabledCalls) != 0 { + var lines []string + for call, reason := range disabledCalls { + lines = append(lines, fmt.Sprintf("%-44v: %v\n", call.Name, reason)) + } + sort.Strings(lines) + fmt.Fprintf(buf, "disabled the following syscalls:\n%s\n", strings.Join(lines, "")) } - for _, id := range serv.cfg.Syscalls { - name := serv.cfg.Target.Syscalls[id].Name - if reason := disabled[name]; reason != "" { - log.Logf(0, "disabling %v: %v", name, reason) + if len(transitivelyDisabled) != 0 { + var lines []string + for call, reason := range transitivelyDisabled { + lines = append(lines, fmt.Sprintf("%-44v: %v\n", call.Name, reason)) } + sort.Strings(lines) + fmt.Fprintf(buf, "transitively disabled the following syscalls"+ + " (missing resource [creating syscalls]):\n%s\n", + strings.Join(lines, "")) } } + if len(enabledCalls) == 0 && a.Error == "" { + a.Error = "all system calls are disabled" + } + hasFileErrors := false for _, file := range a.Files { - if file.Error != "" { - log.Logf(0, "failed to read %q: %v", file.Name, file.Error) + if file.Error == "" { + continue + } + if !hasFileErrors { + fmt.Fprintf(buf, "failed to read the following files in the VM:\n") } + fmt.Fprintf(buf, "%-44v: %v\n", file.Name, file.Error) + hasFileErrors = true } + if hasFileErrors { + fmt.Fprintf(buf, "\n") + } + fmt.Fprintf(buf, "%-24v: %v/%v\n", "syscalls", len(enabledCalls), len(serv.cfg.Target.Syscalls)) + for _, feat := range a.Features.Supported() { + fmt.Fprintf(buf, "%-24v: %v\n", feat.Name, feat.Reason) + } + fmt.Fprintf(buf, "\n") + log.Logf(0, "machine check:\n%s", buf.Bytes()) if a.Error != "" { log.Logf(0, "machine check failed: %v", a.Error) serv.checkFailures++ @@ -214,15 +252,7 @@ func (serv *RPCServer) check(a *rpctype.CheckArgs, modules []host.KernelModule) } return fmt.Errorf("machine check failed: %v", a.Error) } - serv.targetEnabledSyscalls = make(map[*prog.Syscall]bool) - for _, call := range a.EnabledCalls[serv.cfg.Sandbox] { - serv.targetEnabledSyscalls[serv.cfg.Target.Syscalls[call]] = true - } - log.Logf(0, "machine check:") - log.Logf(0, "%-24v: %v/%v", "syscalls", len(serv.targetEnabledSyscalls), len(serv.cfg.Target.Syscalls)) - for _, feat := range a.Features.Supported() { - log.Logf(0, "%-24v: %v", feat.Name, feat.Reason) - } + serv.targetEnabledSyscalls = enabledCalls serv.checkFeatures = a.Features serv.canonicalModules = cover.NewCanonicalizer(modules, serv.cfg.Cover) serv.mgr.machineChecked(a.Features, a.Globs, serv.targetEnabledSyscalls, modules) |
