diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-08-19 00:13:24 -0700 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-08-19 00:13:24 -0700 |
| commit | 2dc4378f0225c80d2755f7531ad0de4c2044727a (patch) | |
| tree | ae59cc84d52549a29d23b69b49db596247881bc0 /prog/prog_test.go | |
| parent | 4e1e8035f3a8696dbf410a4576b51f68f62e6830 (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.go | 153 |
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) + } + } + } + }) + } +} |
