diff options
Diffstat (limited to 'runsc/specutils/seccomp')
-rw-r--r-- | runsc/specutils/seccomp/BUILD | 34 | ||||
-rw-r--r-- | runsc/specutils/seccomp/seccomp_amd64_state_autogen.go | 5 | ||||
-rw-r--r-- | runsc/specutils/seccomp/seccomp_arm64_state_autogen.go | 5 | ||||
-rw-r--r-- | runsc/specutils/seccomp/seccomp_state_autogen.go | 3 | ||||
-rw-r--r-- | runsc/specutils/seccomp/seccomp_test.go | 414 |
5 files changed, 13 insertions, 448 deletions
diff --git a/runsc/specutils/seccomp/BUILD b/runsc/specutils/seccomp/BUILD deleted file mode 100644 index 3520f2d6d..000000000 --- a/runsc/specutils/seccomp/BUILD +++ /dev/null @@ -1,34 +0,0 @@ -load("//tools:defs.bzl", "go_library", "go_test") - -package(licenses = ["notice"]) - -go_library( - name = "seccomp", - srcs = [ - "audit_amd64.go", - "audit_arm64.go", - "seccomp.go", - ], - visibility = ["//:sandbox"], - deps = [ - "//pkg/abi/linux", - "//pkg/bpf", - "//pkg/log", - "//pkg/seccomp", - "//pkg/sentry/kernel", - "//pkg/sentry/syscalls/linux", - "@com_github_opencontainers_runtime_spec//specs-go:go_default_library", - ], -) - -go_test( - name = "seccomp_test", - size = "small", - srcs = ["seccomp_test.go"], - library = ":seccomp", - deps = [ - "//pkg/binary", - "//pkg/bpf", - "@com_github_opencontainers_runtime_spec//specs-go:go_default_library", - ], -) diff --git a/runsc/specutils/seccomp/seccomp_amd64_state_autogen.go b/runsc/specutils/seccomp/seccomp_amd64_state_autogen.go new file mode 100644 index 000000000..27a96018b --- /dev/null +++ b/runsc/specutils/seccomp/seccomp_amd64_state_autogen.go @@ -0,0 +1,5 @@ +// automatically generated by stateify. + +// +build amd64 + +package seccomp diff --git a/runsc/specutils/seccomp/seccomp_arm64_state_autogen.go b/runsc/specutils/seccomp/seccomp_arm64_state_autogen.go new file mode 100644 index 000000000..96c64c23d --- /dev/null +++ b/runsc/specutils/seccomp/seccomp_arm64_state_autogen.go @@ -0,0 +1,5 @@ +// automatically generated by stateify. + +// +build arm64 + +package seccomp diff --git a/runsc/specutils/seccomp/seccomp_state_autogen.go b/runsc/specutils/seccomp/seccomp_state_autogen.go new file mode 100644 index 000000000..e16b5d7c2 --- /dev/null +++ b/runsc/specutils/seccomp/seccomp_state_autogen.go @@ -0,0 +1,3 @@ +// automatically generated by stateify. + +package seccomp diff --git a/runsc/specutils/seccomp/seccomp_test.go b/runsc/specutils/seccomp/seccomp_test.go deleted file mode 100644 index 850c237ba..000000000 --- a/runsc/specutils/seccomp/seccomp_test.go +++ /dev/null @@ -1,414 +0,0 @@ -// Copyright 2020 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package seccomp - -import ( - "fmt" - "syscall" - "testing" - - specs "github.com/opencontainers/runtime-spec/specs-go" - "gvisor.dev/gvisor/pkg/binary" - "gvisor.dev/gvisor/pkg/bpf" -) - -type seccompData struct { - nr uint32 - arch uint32 - instructionPointer uint64 - args [6]uint64 -} - -// asInput converts a seccompData to a bpf.Input. -func asInput(d seccompData) bpf.Input { - return bpf.InputBytes{binary.Marshal(nil, binary.LittleEndian, d), binary.LittleEndian} -} - -// testInput creates an Input struct with given seccomp input values. -func testInput(arch uint32, syscallName string, args *[6]uint64) bpf.Input { - syscallNo, err := lookupSyscallNo(arch, syscallName) - if err != nil { - // Assume tests set valid syscall names. - panic(err) - } - - if args == nil { - argArray := [6]uint64{0, 0, 0, 0, 0, 0} - args = &argArray - } - - data := seccompData{ - nr: syscallNo, - arch: arch, - args: *args, - } - - return asInput(data) -} - -// testCase holds a seccomp test case. -type testCase struct { - name string - config specs.LinuxSeccomp - input bpf.Input - expected uint32 -} - -var ( - // seccompTests is a list of speccomp test cases. - seccompTests = []testCase{ - { - name: "default_allow", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - }, - input: testInput(nativeArchAuditNo, "read", nil), - expected: uint32(allowAction), - }, - { - name: "default_deny", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActErrno, - }, - input: testInput(nativeArchAuditNo, "read", nil), - expected: uint32(errnoAction), - }, - { - name: "deny_arch", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "getcwd", - }, - Action: specs.ActErrno, - }, - }, - }, - // Syscall matches but the arch is AUDIT_ARCH_X86 so the return - // value is the bad arch action. - input: asInput(seccompData{nr: 183, arch: 0x40000003}), // - expected: uint32(killThreadAction), - }, - { - name: "match_name_errno", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "getcwd", - "chmod", - }, - Action: specs.ActErrno, - }, - { - Names: []string{ - "write", - }, - Action: specs.ActTrace, - }, - }, - }, - input: testInput(nativeArchAuditNo, "getcwd", nil), - expected: uint32(errnoAction), - }, - { - name: "match_name_trace", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "getcwd", - "chmod", - }, - Action: specs.ActErrno, - }, - { - Names: []string{ - "write", - }, - Action: specs.ActTrace, - }, - }, - }, - input: testInput(nativeArchAuditNo, "write", nil), - expected: uint32(traceAction), - }, - { - name: "no_match_name_allow", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "getcwd", - "chmod", - }, - Action: specs.ActErrno, - }, - { - Names: []string{ - "write", - }, - Action: specs.ActTrace, - }, - }, - }, - input: testInput(nativeArchAuditNo, "openat", nil), - expected: uint32(allowAction), - }, - { - name: "simple_match_args", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "clone", - }, - Args: []specs.LinuxSeccompArg{ - { - Index: 0, - Value: syscall.CLONE_FS, - Op: specs.OpEqualTo, - }, - }, - Action: specs.ActErrno, - }, - }, - }, - input: testInput(nativeArchAuditNo, "clone", &[6]uint64{syscall.CLONE_FS}), - expected: uint32(errnoAction), - }, - { - name: "match_args_or", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "clone", - }, - Args: []specs.LinuxSeccompArg{ - { - Index: 0, - Value: syscall.CLONE_FS, - Op: specs.OpEqualTo, - }, - { - Index: 0, - Value: syscall.CLONE_VM, - Op: specs.OpEqualTo, - }, - }, - Action: specs.ActErrno, - }, - }, - }, - input: testInput(nativeArchAuditNo, "clone", &[6]uint64{syscall.CLONE_FS}), - expected: uint32(errnoAction), - }, - { - name: "match_args_and", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "getsockopt", - }, - Args: []specs.LinuxSeccompArg{ - { - Index: 1, - Value: syscall.SOL_SOCKET, - Op: specs.OpEqualTo, - }, - { - Index: 2, - Value: syscall.SO_PEERCRED, - Op: specs.OpEqualTo, - }, - }, - Action: specs.ActErrno, - }, - }, - }, - input: testInput(nativeArchAuditNo, "getsockopt", &[6]uint64{0, syscall.SOL_SOCKET, syscall.SO_PEERCRED}), - expected: uint32(errnoAction), - }, - { - name: "no_match_args_and", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "getsockopt", - }, - Args: []specs.LinuxSeccompArg{ - { - Index: 1, - Value: syscall.SOL_SOCKET, - Op: specs.OpEqualTo, - }, - { - Index: 2, - Value: syscall.SO_PEERCRED, - Op: specs.OpEqualTo, - }, - }, - Action: specs.ActErrno, - }, - }, - }, - input: testInput(nativeArchAuditNo, "getsockopt", &[6]uint64{0, syscall.SOL_SOCKET}), - expected: uint32(allowAction), - }, - { - name: "Simple args (no match)", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "clone", - }, - Args: []specs.LinuxSeccompArg{ - { - Index: 0, - Value: syscall.CLONE_FS, - Op: specs.OpEqualTo, - }, - }, - Action: specs.ActErrno, - }, - }, - }, - input: testInput(nativeArchAuditNo, "clone", &[6]uint64{syscall.CLONE_VM}), - expected: uint32(allowAction), - }, - { - name: "OpMaskedEqual (match)", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "clone", - }, - Args: []specs.LinuxSeccompArg{ - { - Index: 0, - Value: syscall.CLONE_FS, - ValueTwo: syscall.CLONE_FS, - Op: specs.OpMaskedEqual, - }, - }, - Action: specs.ActErrno, - }, - }, - }, - input: testInput(nativeArchAuditNo, "clone", &[6]uint64{syscall.CLONE_FS | syscall.CLONE_VM}), - expected: uint32(errnoAction), - }, - { - name: "OpMaskedEqual (no match)", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActAllow, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "clone", - }, - Args: []specs.LinuxSeccompArg{ - { - Index: 0, - Value: syscall.CLONE_FS | syscall.CLONE_VM, - ValueTwo: syscall.CLONE_FS | syscall.CLONE_VM, - Op: specs.OpMaskedEqual, - }, - }, - Action: specs.ActErrno, - }, - }, - }, - input: testInput(nativeArchAuditNo, "clone", &[6]uint64{syscall.CLONE_FS}), - expected: uint32(allowAction), - }, - { - name: "OpMaskedEqual (clone)", - config: specs.LinuxSeccomp{ - DefaultAction: specs.ActErrno, - Syscalls: []specs.LinuxSyscall{ - { - Names: []string{ - "clone", - }, - // This comes from the Docker default seccomp - // profile for clone. - Args: []specs.LinuxSeccompArg{ - { - Index: 0, - Value: 0x7e020000, - ValueTwo: 0x0, - Op: specs.OpMaskedEqual, - }, - }, - Action: specs.ActAllow, - }, - }, - }, - input: testInput(nativeArchAuditNo, "clone", &[6]uint64{0x50f00}), - expected: uint32(allowAction), - }, - } -) - -// TestRunscSeccomp generates seccomp programs from OCI config and executes -// them using runsc's library, comparing against expected results. -func TestRunscSeccomp(t *testing.T) { - for _, tc := range seccompTests { - t.Run(tc.name, func(t *testing.T) { - runscProgram, err := BuildProgram(&tc.config) - if err != nil { - t.Fatalf("generating runsc BPF: %v", err) - } - - if err := checkProgram(runscProgram, tc.input, tc.expected); err != nil { - t.Fatalf("running runsc BPF: %v", err) - } - }) - } -} - -// checkProgram runs the given program over the given input and checks the -// result against the expected output. -func checkProgram(p bpf.Program, in bpf.Input, expected uint32) error { - result, err := bpf.Exec(p, in) - if err != nil { - return err - } - - if result != expected { - // Include a decoded version of the program in output for debugging purposes. - decoded, _ := bpf.DecodeProgram(p) - return fmt.Errorf("Unexpected result: got: %d, expected: %d\nBPF Program\n%s", result, expected, decoded) - } - - return nil -} |