aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-04-29 07:55:46 +0200
committerDmitry Vyukov <dvyukov@google.com>2024-04-29 14:53:56 +0000
commitee51f7ac1dd0df7131343d099fd0b87aac42f360 (patch)
tree4380123b153453dc87b720df601dc8478bfeefa3
parentad452794ee865e84d6bf40479e327aa9d07dec60 (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.go21
-rw-r--r--prog/resources.go7
-rw-r--r--prog/resources_test.go3
-rw-r--r--syz-fuzzer/testing.go11
-rw-r--r--syz-manager/rpc.go68
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)