summaryrefslogtreecommitdiffhomepage
path: root/runsc/specutils/seccomp
diff options
context:
space:
mode:
Diffstat (limited to 'runsc/specutils/seccomp')
-rw-r--r--runsc/specutils/seccomp/BUILD34
-rw-r--r--runsc/specutils/seccomp/seccomp_amd64_state_autogen.go5
-rw-r--r--runsc/specutils/seccomp/seccomp_arm64_state_autogen.go5
-rw-r--r--runsc/specutils/seccomp/seccomp_state_autogen.go3
-rw-r--r--runsc/specutils/seccomp/seccomp_test.go414
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 2079cd2e9..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, "open", 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
-}