aboutsummaryrefslogtreecommitdiffstats
path: root/prog
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-04-06 19:43:06 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-04-06 19:43:06 +0200
commit2a9c3edcdaf644772298c92be942bfbb7170b35c (patch)
tree2affc5164d2fdf4f44a6661a8e22625eabe744f9 /prog
parent4daf8570eba286299489fc3ebc7d788c458bb47a (diff)
pkg/prog: explain why syscalls are transitively disabled
Diffstat (limited to 'prog')
-rw-r--r--prog/decl_test.go36
-rw-r--r--prog/resources.go23
2 files changed, 42 insertions, 17 deletions
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
}