aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/host/host_test.go12
-rw-r--r--prog/decl_test.go36
-rw-r--r--prog/resources.go23
-rw-r--r--syz-fuzzer/fuzzer.go9
-rw-r--r--syz-fuzzer/testing.go2
-rw-r--r--tools/syz-mutate/mutate.go10
-rw-r--r--tools/syz-stress/stress.go11
7 files changed, 57 insertions, 46 deletions
diff --git a/pkg/host/host_test.go b/pkg/host/host_test.go
index 470a6e5e1..aa7020942 100644
--- a/pkg/host/host_test.go
+++ b/pkg/host/host_test.go
@@ -31,15 +31,9 @@ func TestLog(t *testing.T) {
for c, reason := range disabled {
t.Logf("%v: %v", c.Name, reason)
}
- trans := target.TransitivelyEnabledCalls(supp)
+ _, disabled = target.TransitivelyEnabledCalls(supp)
t.Logf("\n\ntransitively unsupported:")
- for _, c := range target.Syscalls {
- s, ok := trans[c]
- if ok && !s {
- t.Fatalf("map contains false value")
- }
- if !s && supp[c] {
- t.Logf("%v", c.Name)
- }
+ for c, reason := range disabled {
+ t.Logf("%v: %v", c.Name, reason)
}
}
diff --git a/prog/decl_test.go b/prog/decl_test.go
index 72a6435e8..4539be2fb 100644
--- a/prog/decl_test.go
+++ b/prog/decl_test.go
@@ -5,6 +5,7 @@ package prog
import (
"runtime"
+ "strings"
"testing"
)
@@ -32,20 +33,26 @@ func TestTransitivelyEnabledCalls(t *testing.T) {
for _, c := range target.Syscalls {
calls[c] = true
}
- if trans := target.TransitivelyEnabledCalls(calls); len(calls) != len(trans) {
- for c := range calls {
- if !trans[c] {
- t.Logf("disabled %v", c.Name)
- }
+ if trans, disabled := target.TransitivelyEnabledCalls(calls); len(disabled) != 0 {
+ for c, reason := range disabled {
+ t.Logf("disabled %v: %v", c.Name, reason)
}
t.Fatalf("can't create some resource")
+ } else if len(trans) != len(calls) {
+ t.Fatalf("transitive syscalls are not full")
+ } else {
+ for c, ok := range trans {
+ if !ok {
+ t.Fatalf("syscalls %v is false in transitive map", c.Name)
+ }
+ }
}
delete(calls, target.SyscallMap["epoll_create"])
- if trans := target.TransitivelyEnabledCalls(calls); len(calls) != len(trans) {
+ if trans, disabled := target.TransitivelyEnabledCalls(calls); len(disabled) != 0 || len(trans) != len(calls) {
t.Fatalf("still must be able to create epoll fd with epoll_create1")
}
delete(calls, target.SyscallMap["epoll_create1"])
- trans := target.TransitivelyEnabledCalls(calls)
+ trans, disabled := target.TransitivelyEnabledCalls(calls)
if len(calls)-6 != len(trans) ||
trans[target.SyscallMap["epoll_ctl$EPOLL_CTL_ADD"]] ||
trans[target.SyscallMap["epoll_ctl$EPOLL_CTL_MOD"]] ||
@@ -55,6 +62,14 @@ func TestTransitivelyEnabledCalls(t *testing.T) {
trans[target.SyscallMap["kcmp$KCMP_EPOLL_TFD"]] {
t.Fatalf("epoll fd is not disabled")
}
+ if len(disabled) != 6 {
+ t.Fatalf("disabled %v syscalls, want 6", 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]") {
+ t.Fatalf("%v: wrong disable reason: %v", c.Name, reason)
+ }
+ }
}
func TestClockGettime(t *testing.T) {
@@ -69,8 +84,9 @@ func TestClockGettime(t *testing.T) {
}
// Removal of clock_gettime should disable all calls that accept timespec/timeval.
delete(calls, target.SyscallMap["clock_gettime"])
- trans := target.TransitivelyEnabledCalls(calls)
- if len(trans)+10 > len(calls) {
- t.Fatalf("clock_gettime did not disable enough calls: before %v, after %v", len(calls), len(trans))
+ trans, disabled := target.TransitivelyEnabledCalls(calls)
+ if len(trans)+10 > len(calls) || len(trans)+len(disabled) != len(calls) || len(trans) == 0 {
+ t.Fatalf("clock_gettime did not disable enough calls: before %v, after %v, disabled %v",
+ len(calls), len(trans), len(disabled))
}
}
diff --git a/prog/resources.go b/prog/resources.go
index e6ef080cd..33c497d5a 100644
--- a/prog/resources.go
+++ b/prog/resources.go
@@ -85,8 +85,9 @@ func (c *Syscall) inputResources() []*ResourceType {
return resources
}
-func (target *Target) TransitivelyEnabledCalls(enabled map[*Syscall]bool) map[*Syscall]bool {
+func (target *Target) TransitivelyEnabledCalls(enabled map[*Syscall]bool) (map[*Syscall]bool, map[*Syscall]string) {
supported := make(map[*Syscall]bool)
+ disabled := make(map[*Syscall]string)
for c := range enabled {
supported[c] = true
}
@@ -106,7 +107,8 @@ func (target *Target) TransitivelyEnabledCalls(enabled map[*Syscall]bool) map[*S
n := len(supported)
haveGettime := supported[target.SyscallMap["clock_gettime"]]
for c := range supported {
- canCreate := true
+ cantCreate := ""
+ var resourceCtors []*Syscall
for _, res := range inputResources[c] {
noctors := true
for _, ctor := range ctors[res.Desc.Name] {
@@ -116,26 +118,33 @@ func (target *Target) TransitivelyEnabledCalls(enabled map[*Syscall]bool) map[*S
}
}
if noctors {
- canCreate = false
+ cantCreate = res.Desc.Name
+ resourceCtors = ctors[res.Desc.Name]
break
}
}
// We need to support structs as resources,
// but for now we just special-case timespec/timeval.
- if canCreate && !haveGettime {
+ if cantCreate == "" && !haveGettime {
ForeachType(c, func(typ Type) {
if a, ok := typ.(*StructType); ok && a.Dir() != DirOut && (a.Name() == "timespec" || a.Name() == "timeval") {
- canCreate = false
+ cantCreate = a.Name()
+ resourceCtors = []*Syscall{target.SyscallMap["clock_gettime"]}
}
})
}
- if !canCreate {
+ if cantCreate != "" {
delete(supported, c)
+ var ctorNames []string
+ for _, ctor := range resourceCtors {
+ ctorNames = append(ctorNames, ctor.Name)
+ }
+ disabled[c] = fmt.Sprintf("no syscalls can create resource %v, enable some syscalls that can create it %v", cantCreate, ctorNames)
}
}
if n == len(supported) {
break
}
}
- return supported
+ return supported, disabled
}
diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go
index 1701f7491..bff1db565 100644
--- a/syz-fuzzer/fuzzer.go
+++ b/syz-fuzzer/fuzzer.go
@@ -404,12 +404,9 @@ func buildCallList(target *prog.Target, enabledCalls, sandbox string) map[*prog.
}
}
- trans := target.TransitivelyEnabledCalls(calls)
- for c := range calls {
- if !trans[c] {
- Logf(1, "transitively unsupported: %v", c.Name)
- delete(calls, c)
- }
+ calls, disabled := target.TransitivelyEnabledCalls(calls)
+ for c, reason := range disabled {
+ Logf(1, "transitively unsupported: %v: %v", c.Name, reason)
}
return calls
}
diff --git a/syz-fuzzer/testing.go b/syz-fuzzer/testing.go
index 257d63855..57906c407 100644
--- a/syz-fuzzer/testing.go
+++ b/syz-fuzzer/testing.go
@@ -36,7 +36,7 @@ func testImage(hostAddr string, target *prog.Target, sandbox string) {
if err != nil {
Fatalf("failed to detect supported syscalls: %v", err)
}
- calls = target.TransitivelyEnabledCalls(calls)
+ calls, _ = target.TransitivelyEnabledCalls(calls)
Logf(0, "enabled syscalls: %v", len(calls))
if calls[target.SyscallMap["syz_emit_ethernet"]] ||
calls[target.SyscallMap["syz_extract_tcp_res"]] {
diff --git a/tools/syz-mutate/mutate.go b/tools/syz-mutate/mutate.go
index 4cf3401bc..73957c246 100644
--- a/tools/syz-mutate/mutate.go
+++ b/tools/syz-mutate/mutate.go
@@ -45,12 +45,10 @@ func main() {
for id := range syscallsIDs {
syscalls[target.Syscalls[id]] = true
}
- trans := target.TransitivelyEnabledCalls(syscalls)
- for c := range syscalls {
- if !trans[c] {
- fmt.Fprintf(os.Stderr, "disabling %v\n", c.Name)
- delete(syscalls, c)
- }
+ var disabled map[*prog.Syscall]string
+ syscalls, disabled = target.TransitivelyEnabledCalls(syscalls)
+ for c, reason := range disabled {
+ fmt.Fprintf(os.Stderr, "disabling %v: %v\n", c.Name, reason)
}
}
seed := time.Now().UnixNano()
diff --git a/tools/syz-stress/stress.go b/tools/syz-stress/stress.go
index 73073c392..2736c2f6f 100644
--- a/tools/syz-stress/stress.go
+++ b/tools/syz-stress/stress.go
@@ -148,14 +148,11 @@ func buildCallList(target *prog.Target) map[*prog.Syscall]bool {
}
}
for c, reason := range disabled {
- Logf(0, "disabling unsupported syscall: %v: %v", c.Name, reason)
+ Logf(0, "unsupported syscall: %v: %v", c.Name, reason)
}
- trans := target.TransitivelyEnabledCalls(calls)
- for c := range calls {
- if !trans[c] {
- Logf(0, "disabling transitively unsupported syscall: %v", c.Name)
- delete(calls, c)
- }
+ calls, disabled = target.TransitivelyEnabledCalls(calls)
+ for c, reason := range disabled {
+ Logf(0, "transitively unsupported: %v: %v", c.Name, reason)
}
return calls
}