From 006a4e3303aab431280e53028692e3ac29a7d74a Mon Sep 17 00:00:00 2001 From: Alban Crequy Date: Tue, 22 Feb 2022 15:58:46 +0100 Subject: [PATCH] seccomp: add support for SECCOMP_FILTER_FLAG_LOG Signed-off-by: Alban Crequy --- libcontainer/configs/config.go | 1 + libcontainer/seccomp/seccomp_linux.go | 12 ++++++++++++ libcontainer/specconv/spec_linux.go | 15 ++++++++++----- tests/integration/seccomp.bats | 16 ++++++++++++++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go index 7cf2fb65751..91a3bc3ecac 100644 --- a/libcontainer/configs/config.go +++ b/libcontainer/configs/config.go @@ -33,6 +33,7 @@ type IDMap struct { type Seccomp struct { DefaultAction Action `json:"default_action"` Architectures []string `json:"architectures"` + Flags []string `json:"flags"` Syscalls []*Syscall `json:"syscalls"` DefaultErrnoRet *uint `json:"default_errno_ret"` ListenerPath string `json:"listener_path,omitempty"` diff --git a/libcontainer/seccomp/seccomp_linux.go b/libcontainer/seccomp/seccomp_linux.go index f177b7f05f2..d72faa45945 100644 --- a/libcontainer/seccomp/seccomp_linux.go +++ b/libcontainer/seccomp/seccomp_linux.go @@ -86,6 +86,18 @@ func InitSeccomp(config *configs.Seccomp) (int, error) { } } + // Add extra flags + for _, flag := range config.Flags { + switch flag { + case "SECCOMP_FILTER_FLAG_LOG": + if err := filter.SetLogBit(true); err != nil { + return -1, fmt.Errorf("error adding log flag to seccomp filter: %w", err) + } + default: + return -1, fmt.Errorf("seccomp flags %q not yet supported by runc", flag) + } + } + // Unset no new privs bit if err := filter.SetNoNewPrivsBit(false); err != nil { return -1, fmt.Errorf("error setting no new privileges: %w", err) diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go index fad7b802e1c..db24c4bf71d 100644 --- a/libcontainer/specconv/spec_linux.go +++ b/libcontainer/specconv/spec_linux.go @@ -1016,14 +1016,19 @@ func SetupSeccomp(config *specs.LinuxSeccomp) (*configs.Seccomp, error) { return nil, nil } - // We don't currently support seccomp flags. - if len(config.Flags) != 0 { - return nil, errors.New("seccomp flags are not yet supported by runc") - } - newConfig := new(configs.Seccomp) newConfig.Syscalls = []*configs.Syscall{} + // We don't currently support all seccomp flags. + for _, flag := range config.Flags { + switch flag { + case "SECCOMP_FILTER_FLAG_LOG": + newConfig.Flags = append(newConfig.Flags, "SECCOMP_FILTER_FLAG_LOG") + default: + return nil, fmt.Errorf("seccomp flags %q not yet supported by runc", flag) + } + } + if len(config.Architectures) > 0 { newConfig.Architectures = []string{} for _, arch := range config.Architectures { diff --git a/tests/integration/seccomp.bats b/tests/integration/seccomp.bats index e81beca3357..016dca49ee7 100644 --- a/tests/integration/seccomp.bats +++ b/tests/integration/seccomp.bats @@ -66,6 +66,22 @@ function teardown() { [[ "$output" == *"Network is down"* ]] } +@test "runc run [seccomp] (SECCOMP_FILTER_FLAG_LOG)" { + requires_kernel 4.14 # SECCOMP_FILTER_FLAG_LOG appeared in Linux 4.14 + update_config ' .process.args = ["/bin/sh", "-c", "mkdir /dev/shm/foo"] + | .process.noNewPrivileges = false + | .linux.seccomp = { + "defaultAction":"SCMP_ACT_ALLOW", + "architectures":["SCMP_ARCH_X86","SCMP_ARCH_X32"], + "flags":["SECCOMP_FILTER_FLAG_LOG"], + "syscalls":[{"names":["mkdir"], "action":"SCMP_ACT_ERRNO"}] + }' + + runc run test_busybox + [ "$status" -ne 0 ] + [[ "$output" == *"mkdir:"*"/dev/shm/foo"*"Operation not permitted"* ]] +} + @test "runc run [seccomp] (SCMP_ACT_KILL)" { update_config ' .process.args = ["/bin/sh", "-c", "mkdir /dev/shm/foo"] | .process.noNewPrivileges = false