mirror of
https://github.com/opencontainers/runc.git
synced 2026-04-24 16:39:52 +08:00
0079bee17f
This adds support for WaitKillableRecv seccomp flag (also known as SCMP_FLTATR_CTL_WAITKILL in libseccomp and as SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV in the kernel). This requires: - libseccomp >= 2.6.0 - libseccomp-golang >= 0.11.0 - linux kernel >= 5.19 Note that this flag does not make sense without NEW_LISTENER, and the kernel returns EINVAL when SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV is set but SECCOMP_FILTER_FLAG_NEW_LISTENER is not set. For runc this means that .linux.seccomp.listenerPath should also be set, and some of the seccomp rules should have SCMP_ACT_NOTIFY action. This is why the flag is tested separately in seccomp-notify.bats. At the moment the only adequate CI environment for this functionality is Fedora 43. On all other platforms (including CentOS 10 and Ubuntu 24.04) it is skipped similar to this: > ok 251 runc run [seccomp] (SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV) # skip requires libseccomp >= 2.6.0 and API level >= 7 (current version: 2.5.6, API level: 6) Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
139 lines
4.1 KiB
Go
139 lines
4.1 KiB
Go
package seccomp
|
|
|
|
import (
|
|
"fmt"
|
|
"maps"
|
|
"slices"
|
|
|
|
"github.com/opencontainers/runc/libcontainer/configs"
|
|
"github.com/opencontainers/runtime-spec/specs-go"
|
|
)
|
|
|
|
// flagTsync is recognized but ignored by runc, and it is not defined
|
|
// in the runtime-spec.
|
|
const flagTsync = "SECCOMP_FILTER_FLAG_TSYNC"
|
|
|
|
var operators = map[string]configs.Operator{
|
|
"SCMP_CMP_NE": configs.NotEqualTo,
|
|
"SCMP_CMP_LT": configs.LessThan,
|
|
"SCMP_CMP_LE": configs.LessThanOrEqualTo,
|
|
"SCMP_CMP_EQ": configs.EqualTo,
|
|
"SCMP_CMP_GE": configs.GreaterThanOrEqualTo,
|
|
"SCMP_CMP_GT": configs.GreaterThan,
|
|
"SCMP_CMP_MASKED_EQ": configs.MaskEqualTo,
|
|
}
|
|
|
|
// KnownOperators returns the list of the known operations.
|
|
// Used by `runc features`.
|
|
func KnownOperators() []string {
|
|
return slices.Sorted(maps.Keys(operators))
|
|
}
|
|
|
|
var actions = map[string]configs.Action{
|
|
"SCMP_ACT_KILL": configs.Kill,
|
|
"SCMP_ACT_ERRNO": configs.Errno,
|
|
"SCMP_ACT_TRAP": configs.Trap,
|
|
"SCMP_ACT_ALLOW": configs.Allow,
|
|
"SCMP_ACT_TRACE": configs.Trace,
|
|
"SCMP_ACT_LOG": configs.Log,
|
|
"SCMP_ACT_NOTIFY": configs.Notify,
|
|
"SCMP_ACT_KILL_THREAD": configs.KillThread,
|
|
"SCMP_ACT_KILL_PROCESS": configs.KillProcess,
|
|
}
|
|
|
|
// KnownActions returns the list of the known actions.
|
|
// Used by `runc features`.
|
|
func KnownActions() []string {
|
|
return slices.Sorted(maps.Keys(actions))
|
|
}
|
|
|
|
var archs = map[string]string{
|
|
"SCMP_ARCH_X86": "x86",
|
|
"SCMP_ARCH_X86_64": "amd64",
|
|
"SCMP_ARCH_X32": "x32",
|
|
"SCMP_ARCH_ARM": "arm",
|
|
"SCMP_ARCH_AARCH64": "arm64",
|
|
"SCMP_ARCH_MIPS": "mips",
|
|
"SCMP_ARCH_MIPS64": "mips64",
|
|
"SCMP_ARCH_MIPS64N32": "mips64n32",
|
|
"SCMP_ARCH_MIPSEL": "mipsel",
|
|
"SCMP_ARCH_MIPSEL64": "mipsel64",
|
|
"SCMP_ARCH_MIPSEL64N32": "mipsel64n32",
|
|
"SCMP_ARCH_PPC": "ppc",
|
|
"SCMP_ARCH_PPC64": "ppc64",
|
|
"SCMP_ARCH_PPC64LE": "ppc64le",
|
|
"SCMP_ARCH_RISCV64": "riscv64",
|
|
"SCMP_ARCH_S390": "s390",
|
|
"SCMP_ARCH_S390X": "s390x",
|
|
"SCMP_ARCH_LOONGARCH64": "loong64",
|
|
}
|
|
|
|
// KnownArchs returns the list of the known archs.
|
|
// Used by `runc features`.
|
|
func KnownArchs() []string {
|
|
return slices.Sorted(maps.Keys(archs))
|
|
}
|
|
|
|
// ConvertStringToOperator converts a string into a Seccomp comparison operator.
|
|
// Comparison operators use the names they are assigned by Libseccomp's header.
|
|
// Attempting to convert a string that is not a valid operator results in an
|
|
// error.
|
|
func ConvertStringToOperator(in string) (configs.Operator, error) {
|
|
if op, ok := operators[in]; ok {
|
|
return op, nil
|
|
}
|
|
return 0, fmt.Errorf("string %s is not a valid operator for seccomp", in)
|
|
}
|
|
|
|
// ConvertStringToAction converts a string into a Seccomp rule match action.
|
|
// Actions use the names they are assigned in Libseccomp's header.
|
|
// Attempting to convert a string that is not a valid action results in an
|
|
// error.
|
|
func ConvertStringToAction(in string) (configs.Action, error) {
|
|
if act, ok := actions[in]; ok {
|
|
return act, nil
|
|
}
|
|
return 0, fmt.Errorf("string %s is not a valid action for seccomp", in)
|
|
}
|
|
|
|
// ConvertStringToArch converts a string into a Seccomp comparison arch.
|
|
func ConvertStringToArch(in string) (string, error) {
|
|
if arch, ok := archs[in]; ok {
|
|
return arch, nil
|
|
}
|
|
return "", fmt.Errorf("string %s is not a valid arch for seccomp", in)
|
|
}
|
|
|
|
// List of flags known to this version of runc.
|
|
var flags = []string{
|
|
flagTsync,
|
|
string(specs.LinuxSeccompFlagSpecAllow),
|
|
string(specs.LinuxSeccompFlagLog),
|
|
string(specs.LinuxSeccompFlagWaitKillableRecv),
|
|
}
|
|
|
|
// KnownFlags returns the list of the known filter flags.
|
|
// Used by `runc features`.
|
|
func KnownFlags() []string {
|
|
return flags
|
|
}
|
|
|
|
// SupportedFlags returns the list of the supported filter flags.
|
|
// This list may be a subset of one returned by KnownFlags due to
|
|
// some flags not supported by the current kernel and/or libseccomp.
|
|
// Used by `runc features`.
|
|
func SupportedFlags() []string {
|
|
if !Enabled {
|
|
return nil
|
|
}
|
|
|
|
var res []string
|
|
for _, flag := range flags {
|
|
if FlagSupported(specs.LinuxSeccompFlag(flag)) == nil {
|
|
res = append(res, flag)
|
|
}
|
|
}
|
|
|
|
return res
|
|
}
|