aboutsummaryrefslogtreecommitdiffstats
path: root/prog/prog_test.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-08-19 00:13:24 -0700
committerDmitry Vyukov <dvyukov@google.com>2018-08-19 00:13:24 -0700
commit2dc4378f0225c80d2755f7531ad0de4c2044727a (patch)
treeae59cc84d52549a29d23b69b49db596247881bc0 /prog/prog_test.go
parent4e1e8035f3a8696dbf410a4576b51f68f62e6830 (diff)
prog: don't add fallback signal after seccomp
seccomp filter can produce arbitrary errno values for subsequent syscalls. Don't trust anything afterwards.
Diffstat (limited to 'prog/prog_test.go')
-rw-r--r--prog/prog_test.go153
1 files changed, 153 insertions, 0 deletions
diff --git a/prog/prog_test.go b/prog/prog_test.go
index c3f20bd6d..967b93210 100644
--- a/prog/prog_test.go
+++ b/prog/prog_test.go
@@ -244,3 +244,156 @@ func TestEscapingPaths(t *testing.T) {
}
}
}
+
+func TestFallbackSignal(t *testing.T) {
+ type desc struct {
+ prog string
+ info []CallInfo
+ }
+ tests := []desc{
+ // Test restored errno values and that non-executed syscalls don't get fallback signal.
+ {
+ `
+fallback$0()
+fallback$0()
+fallback$0()
+`,
+ []CallInfo{
+ {
+ Flags: CallExecuted,
+ Errno: 0,
+ Signal: make([]uint32, 1),
+ },
+ {
+ Flags: CallExecuted,
+ Errno: 42,
+ Signal: make([]uint32, 1),
+ },
+ {},
+ },
+ },
+ // Test different cases of argument-dependent signal and that unsuccessful calls don't get it.
+ {
+ `
+r0 = fallback$0()
+fallback$1(r0)
+fallback$1(r0)
+fallback$1(0xffffffffffffffff)
+fallback$1(0x0)
+fallback$1(0x0)
+`,
+ []CallInfo{
+ {
+ Flags: CallExecuted,
+ Errno: 0,
+ Signal: make([]uint32, 1),
+ },
+ {
+ Flags: CallExecuted,
+ Errno: 1,
+ Signal: make([]uint32, 1),
+ },
+ {
+ Flags: CallExecuted,
+ Errno: 0,
+ Signal: make([]uint32, 2),
+ },
+ {
+ Flags: CallExecuted,
+ Errno: 0,
+ Signal: make([]uint32, 1),
+ },
+ {
+ Flags: CallExecuted,
+ Errno: 0,
+ Signal: make([]uint32, 2),
+ },
+ {
+ Flags: CallExecuted,
+ Errno: 2,
+ Signal: make([]uint32, 1),
+ },
+ },
+ },
+ // Test that calls get no signal after a successful seccomp.
+ {
+ `
+fallback$0()
+fallback$0()
+seccomp()
+fallback$0()
+seccomp()
+fallback$0()
+fallback$0()
+`,
+ []CallInfo{
+ {
+ Flags: CallExecuted,
+ Errno: 0,
+ Signal: make([]uint32, 1),
+ },
+ {
+ Flags: CallExecuted,
+ Errno: 0,
+ Signal: make([]uint32, 1),
+ },
+ {
+ Flags: CallExecuted,
+ Errno: 1,
+ Signal: make([]uint32, 1),
+ },
+ {
+ Flags: CallExecuted,
+ Errno: 0,
+ Signal: make([]uint32, 1),
+ },
+ {
+ Flags: CallExecuted,
+ Errno: 0,
+ Signal: make([]uint32, 1),
+ },
+ {
+ Flags: CallExecuted,
+ },
+ {
+ Flags: CallExecuted,
+ },
+ },
+ },
+ }
+ target, err := GetTarget("test", "64")
+ if err != nil {
+ t.Fatal(err)
+ }
+ for i, test := range tests {
+ t.Run(fmt.Sprint(i), func(t *testing.T) {
+ p, err := target.Deserialize([]byte(test.prog))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(p.Calls) != len(test.info) {
+ t.Fatalf("call=%v info=%v", len(p.Calls), len(test.info))
+ }
+ wantSignal := make([]int, len(test.info))
+ for i := range test.info {
+ wantSignal[i] = len(test.info[i].Signal)
+ test.info[i].Signal = nil
+ }
+ p.FallbackSignal(test.info)
+ for i := range test.info {
+ if len(test.info[i].Signal) != wantSignal[i] {
+ t.Errorf("call %v: signal=%v want=%v", i, len(test.info[i].Signal), wantSignal[i])
+ }
+ for _, sig := range test.info[i].Signal {
+ call, errno := DecodeFallbackSignal(sig)
+ if call != p.Calls[i].Meta.ID {
+ t.Errorf("call %v: sig=%x id=%v want=%v", i, sig, call, p.Calls[i].Meta.ID)
+ }
+ if errno != test.info[i].Errno {
+ t.Errorf("call %v: sig=%x errno=%v want=%v", i, sig, errno, test.info[i].Errno)
+ }
+ }
+ }
+ })
+ }
+}