aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKris Alder <kalder@google.com>2022-03-07 23:00:21 +0000
committerAleksandr Nogikh <wp32pw@gmail.com>2022-03-08 16:54:29 +0100
commit9e8eaa75a18a5cf8102e862be692c0781759e51b (patch)
treeb253a2b502230a21593f5e923f99f282a9c78966
parenta5b3b10236688cbda247663ecf994584548f3ef0 (diff)
pkg/host: only try enabled syscalls when starting syz-fuzzer
When syz-fuzzer starts, it tries all syscalls to filter out any that are not supported. This process should include only the syscalls that are enabled using the 'enable_syscalls' and 'disable_syscalls' fields in syz-manager's config. This is useful for fuzzing Cuttlefish devices, for example, where the 'vhost_vsock' syscall needs to be excluded from fuzzing and from this test.
-rw-r--r--pkg/host/host_test.go6
-rw-r--r--pkg/host/syscalls.go5
-rw-r--r--pkg/host/syscalls_linux_test.go16
-rw-r--r--pkg/runtest/run_test.go6
-rw-r--r--syz-fuzzer/testing.go3
-rw-r--r--syz-runner/runner.go6
-rw-r--r--tools/syz-stress/stress.go23
7 files changed, 39 insertions, 26 deletions
diff --git a/pkg/host/host_test.go b/pkg/host/host_test.go
index dc8565920..6e9770744 100644
--- a/pkg/host/host_test.go
+++ b/pkg/host/host_test.go
@@ -23,8 +23,12 @@ func TestDetectSupportedSyscalls(t *testing.T) {
if err != nil {
t.Fatal(err)
}
+ enabled := make(map[*prog.Syscall]bool)
+ for _, c := range target.Syscalls {
+ enabled[c] = true
+ }
// Dump for manual inspection.
- supp, disabled, err := DetectSupportedSyscalls(target, "none")
+ supp, disabled, err := DetectSupportedSyscalls(target, "none", enabled)
if err != nil {
t.Fatal(err)
}
diff --git a/pkg/host/syscalls.go b/pkg/host/syscalls.go
index c6424bfe4..fd8acc4d1 100644
--- a/pkg/host/syscalls.go
+++ b/pkg/host/syscalls.go
@@ -10,7 +10,7 @@ import (
// DetectSupportedSyscalls returns list on supported and unsupported syscalls on the host.
// For unsupported syscalls it also returns reason as to why it is unsupported.
-func DetectSupportedSyscalls(target *prog.Target, sandbox string) (
+func DetectSupportedSyscalls(target *prog.Target, sandbox string, enabled map[*prog.Syscall]bool) (
map[*prog.Syscall]bool, map[*prog.Syscall]string, error) {
log.Logf(1, "detecting supported syscalls")
supported := make(map[*prog.Syscall]bool)
@@ -32,6 +32,9 @@ func DetectSupportedSyscalls(target *prog.Target, sandbox string) (
case c.Attrs.Disabled:
ok = false
reason = disabledAttribute
+ case !enabled[c]:
+ ok = false
+ reason = "not in set of enabled calls"
case c.CallName == "syz_execute_func":
// syz_execute_func caused multiple problems:
// 1. First it lead to corpus explosion. The program used existing values in registers
diff --git a/pkg/host/syscalls_linux_test.go b/pkg/host/syscalls_linux_test.go
index 5fc87377c..97f11c25f 100644
--- a/pkg/host/syscalls_linux_test.go
+++ b/pkg/host/syscalls_linux_test.go
@@ -22,10 +22,6 @@ func TestSupportedSyscalls(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- supp, _, err := DetectSupportedSyscalls(target, "none")
- if err != nil {
- t.Skipf("skipping: %v", err)
- }
// These are safe to execute with invalid arguments.
safe := []string{
"memfd_create",
@@ -37,18 +33,26 @@ func TestSupportedSyscalls(t *testing.T) {
"write",
"stat",
}
+ enabled := make(map[*prog.Syscall]bool)
for _, name := range safe {
c := target.SyscallMap[name]
if c == nil {
t.Fatalf("can't find syscall '%v'", name)
}
+ enabled[c] = true
+ }
+ supp, _, err := DetectSupportedSyscalls(target, "none", enabled)
+ if err != nil {
+ t.Skipf("skipping: %v", err)
+ }
+ for c := range enabled {
a := ^uintptr(0) - 4097 // hopefully invalid
_, _, err := syscall.Syscall6(uintptr(c.NR), a, a, a, a, a, a)
if err == 0 {
- t.Fatalf("%v did not fail", name)
+ t.Fatalf("%v did not fail", c.Name)
}
if ok := err != syscall.ENOSYS; ok != supp[c] {
- t.Fatalf("syscall %v: perse=%v kallsyms=%v", name, ok, supp[c])
+ t.Fatalf("syscall %v: perse=%v kallsyms=%v", c.Name, ok, supp[c])
}
}
}
diff --git a/pkg/runtest/run_test.go b/pkg/runtest/run_test.go
index adafedab2..bc71a9f08 100644
--- a/pkg/runtest/run_test.go
+++ b/pkg/runtest/run_test.go
@@ -58,7 +58,11 @@ func test(t *testing.T, sysTarget *targets.Target) {
if err != nil {
t.Fatalf("failed to detect host features: %v", err)
}
- calls, _, err := host.DetectSupportedSyscalls(target, "none")
+ enabled := make(map[*prog.Syscall]bool)
+ for _, c := range target.Syscalls {
+ enabled[c] = true
+ }
+ calls, _, err := host.DetectSupportedSyscalls(target, "none", enabled)
if err != nil {
t.Fatalf("failed to detect supported syscalls: %v", err)
}
diff --git a/syz-fuzzer/testing.go b/syz-fuzzer/testing.go
index 6274c3174..a754a6afd 100644
--- a/syz-fuzzer/testing.go
+++ b/syz-fuzzer/testing.go
@@ -294,7 +294,8 @@ func buildCallList(target *prog.Target, enabledCalls []int, sandbox string) (
calls[c] = true
}
}
- _, unsupported, err := host.DetectSupportedSyscalls(target, sandbox)
+
+ _, unsupported, err := host.DetectSupportedSyscalls(target, sandbox, calls)
if err != nil {
return nil, nil, fmt.Errorf("failed to detect host supported syscalls: %v", err)
}
diff --git a/syz-runner/runner.go b/syz-runner/runner.go
index 9317055d4..a8965bbc3 100644
--- a/syz-runner/runner.go
+++ b/syz-runner/runner.go
@@ -70,8 +70,12 @@ func main() {
log.Fatalf("failed to connect to verifier: %v", err)
}
+ enabled := make(map[*prog.Syscall]bool)
+ for _, c := range target.Syscalls {
+ enabled[c] = true
+ }
if r.CheckUnsupportedCalls {
- _, unsupported, err := host.DetectSupportedSyscalls(target, ipc.FlagsToSandbox(config.Flags))
+ _, unsupported, err := host.DetectSupportedSyscalls(target, ipc.FlagsToSandbox(config.Flags), enabled)
if err != nil {
log.Fatalf("failed to get unsupported system calls: %v", err)
}
diff --git a/tools/syz-stress/stress.go b/tools/syz-stress/stress.go
index 2122774b6..0b12fc65b 100644
--- a/tools/syz-stress/stress.go
+++ b/tools/syz-stress/stress.go
@@ -186,30 +186,23 @@ func buildCallList(target *prog.Target, enabled []string) map[*prog.Syscall]bool
}
return calls
}
- calls, disabled, err := host.DetectSupportedSyscalls(target, "none")
- if err != nil {
- log.Fatalf("failed to detect host supported syscalls: %v", err)
- }
+
+ enabledSyscalls := make(map[*prog.Syscall]bool)
if len(enabled) != 0 {
syscallsIDs, err := mgrconfig.ParseEnabledSyscalls(target, enabled, nil)
if err != nil {
log.Fatalf("failed to parse enabled syscalls: %v", err)
}
- enabledSyscalls := make(map[*prog.Syscall]bool)
for _, id := range syscallsIDs {
enabledSyscalls[target.Syscalls[id]] = true
}
- for c := range calls {
- if !enabledSyscalls[c] {
- delete(calls, c)
- }
- }
- for c := range disabled {
- if !enabledSyscalls[c] {
- delete(disabled, c)
- }
- }
}
+
+ calls, disabled, err := host.DetectSupportedSyscalls(target, "none", enabledSyscalls)
+ if err != nil {
+ log.Fatalf("failed to detect host supported syscalls: %v", err)
+ }
+
for c, reason := range disabled {
log.Logf(0, "unsupported syscall: %v: %v", c.Name, reason)
}