diff --git a/go.mod b/go.mod index 4507bff5310..555257cbae8 100644 --- a/go.mod +++ b/go.mod @@ -56,7 +56,7 @@ require ( github.com/mvdan/xurls v1.1.0 github.com/onsi/ginkgo v1.14.0 github.com/onsi/gomega v1.10.1 - github.com/opencontainers/runc v1.1.1 + github.com/opencontainers/runc v1.1.3 github.com/opencontainers/selinux v1.10.0 github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 @@ -216,7 +216,7 @@ require ( github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021 // indirect github.com/russross/blackfriday v1.5.2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921 // indirect + github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 // indirect github.com/sirupsen/logrus v1.8.1 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect @@ -456,7 +456,7 @@ replace ( github.com/onsi/gomega => github.com/onsi/gomega v1.10.1 github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.2 - github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1 + github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.3 github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 github.com/opencontainers/selinux => github.com/opencontainers/selinux v1.10.0 github.com/opentracing/opentracing-go => github.com/opentracing/opentracing-go v1.1.0 @@ -477,7 +477,7 @@ replace ( github.com/rubiojr/go-vhd => github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021 github.com/russross/blackfriday => github.com/russross/blackfriday v1.5.2 github.com/russross/blackfriday/v2 => github.com/russross/blackfriday/v2 v2.1.0 - github.com/seccomp/libseccomp-golang => github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921 + github.com/seccomp/libseccomp-golang => github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 github.com/sergi/go-diff => github.com/sergi/go-diff v1.1.0 github.com/sirupsen/logrus => github.com/sirupsen/logrus v1.8.1 github.com/smartystreets/assertions => github.com/smartystreets/assertions v1.1.0 diff --git a/go.sum b/go.sum index b6a4b1ae7d4..d27837a7749 100644 --- a/go.sum +++ b/go.sum @@ -337,8 +337,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v1.1.1 h1:PJ9DSs2sVwE0iVr++pAHE6QkS9tzcVWozlPifdwMgrU= -github.com/opencontainers/runc v1.1.1/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= +github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= +github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.10.0 h1:rAiKF8hTcgLI3w0DHm6i0ylVVcOrlgR1kK99DRLDhyU= @@ -374,8 +374,8 @@ github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNue github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921 h1:58EBmR2dMNL2n/FnbQewK3D14nXr0V9CObDSvMJLq+Y= -github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 h1:RpforrEYXWkmGwJHIGnLZ3tTWStkjVVstwzNGqxX2Ds= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= diff --git a/vendor/github.com/opencontainers/runc/libcontainer/README.md b/vendor/github.com/opencontainers/runc/libcontainer/README.md index 0d91fb71d54..211c8c91e05 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/README.md +++ b/vendor/github.com/opencontainers/runc/libcontainer/README.md @@ -96,22 +96,6 @@ config := &configs.Config{ "CAP_KILL", "CAP_AUDIT_WRITE", }, - Inheritable: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, Permitted: []string{ "CAP_CHOWN", "CAP_DAC_OVERRIDE", diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/common.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/common.go index 98ccc51655c..5a68a3cf394 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/common.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/common.go @@ -289,7 +289,13 @@ func generateDeviceProperties(r *configs.Resources) ([]systemdDbus.Property, err entry.Path = fmt.Sprintf("/dev/char/%d:%d", rule.Major, rule.Minor) } } - deviceAllowList = append(deviceAllowList, entry) + // systemd will issue a warning if the path we give here doesn't exist. + // Since all of this logic is best-effort anyway (we manually set these + // rules separately to systemd) we can safely skip entries that don't + // have a corresponding path. + if _, err := os.Stat(entry.Path); err == nil { + deviceAllowList = append(deviceAllowList, entry) + } } properties = append(properties, newProp("DeviceAllow", deviceAllowList)) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/dbus.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/dbus.go index 3e547e282b5..bb87ae83aef 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/dbus.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/dbus.go @@ -2,6 +2,7 @@ package systemd import ( "context" + "errors" "fmt" "sync" @@ -80,8 +81,6 @@ func (d *dbusConnManager) resetConnection(conn *systemdDbus.Conn) { } } -var errDbusConnClosed = dbus.ErrClosed.Error() - // retryOnDisconnect calls op, and if the error it returns is about closed dbus // connection, the connection is re-established and the op is retried. This helps // with the situation when dbus is restarted and we have a stale connection. @@ -92,7 +91,10 @@ func (d *dbusConnManager) retryOnDisconnect(op func(*systemdDbus.Conn) error) er return err } err = op(conn) - if !isDbusError(err, errDbusConnClosed) { + if err == nil { + return nil + } + if !errors.Is(err, dbus.ErrClosed) { return err } d.resetConnection(conn) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go index 023d623f370..e6c71ac34e3 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go @@ -338,7 +338,12 @@ func (l *LinuxFactory) StartInitialization() (err error) { defer func() { if e := recover(); e != nil { - err = fmt.Errorf("panic from initialization: %w, %v", e, string(debug.Stack())) + if e, ok := e.(error); ok { + err = fmt.Errorf("panic from initialization: %w, %s", e, debug.Stack()) + } else { + //nolint:errorlint // here e is not of error type + err = fmt.Errorf("panic from initialization: %v, %s", e, debug.Stack()) + } } }() diff --git a/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go index e025445d330..446649af843 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go @@ -39,13 +39,9 @@ type parentProcess interface { // startTime returns the process start time. startTime() (uint64, error) - signal(os.Signal) error - externalDescriptors() []string - setExternalDescriptors(fds []string) - forwardChildLogs() chan error } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go index 51660f5efb9..3cfd2bf1e43 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go @@ -577,6 +577,7 @@ func checkProcMount(rootfs, dest, source string) error { "/proc/loadavg", "/proc/slabinfo", "/proc/net/dev", + "/proc/sys/kernel/ns_last_pid", } for _, valid := range validProcMounts { path, err := filepath.Rel(filepath.Join(rootfs, valid), dest) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go index d0c9bb71fb0..98e08e8f0b6 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go @@ -29,13 +29,15 @@ func KnownOperators() []string { } 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": 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. diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go index dfb8a0a8e59..7d4ec6a42e5 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go @@ -72,6 +72,11 @@ import "C" var retErrnoEnosys = uint32(C.C_ACT_ERRNO_ENOSYS) +// This syscall is used for multiplexing "large" syscalls on s390(x). Unknown +// syscalls will end up with this syscall number, so we need to explcitly +// return -ENOSYS for this syscall on those architectures. +const s390xMultiplexSyscall libseccomp.ScmpSyscall = 0 + func isAllowAction(action configs.Action) bool { switch action { // Trace is considered an "allow" action because a good tracer should @@ -305,7 +310,7 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error) // directly from the arch code so we need to do it here. Sadly we can't // share this code between architecture branches. section := []bpf.Instruction{ - // load [0] + // load [0] (syscall number) bpf.LoadAbsolute{Off: 0, Size: 4}, // NOTE: We assume sizeof(int) == 4. } @@ -314,10 +319,37 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error) // No syscalls found for this arch -- skip it and move on. continue case 1: - // Get the only syscall in the map. - var sysno libseccomp.ScmpSyscall - for _, no := range maxSyscalls { + // Get the only syscall and scmpArch in the map. + var ( + scmpArch libseccomp.ScmpArch + sysno libseccomp.ScmpSyscall + ) + for arch, no := range maxSyscalls { sysno = no + scmpArch = arch + } + + switch scmpArch { + // Return -ENOSYS for setup(2) on s390(x). This syscall is used for + // multiplexing "large syscall number" syscalls, but if the syscall + // number is not known to the kernel then the syscall number is + // left unchanged (and because it is sysno=0, you'll end up with + // EPERM for syscalls the kernel doesn't know about). + // + // The actual setup(2) syscall is never used by userspace anymore + // (and hasn't existed for decades) outside of this multiplexing + // scheme so returning -ENOSYS is fine. + case libseccomp.ArchS390, libseccomp.ArchS390X: + section = append(section, []bpf.Instruction{ + // jne [setup=0],1 + bpf.JumpIf{ + Cond: bpf.JumpNotEqual, + Val: uint32(s390xMultiplexSyscall), + SkipTrue: 1, + }, + // ret [ENOSYS] + bpf.RetConstant{Val: retErrnoEnosys}, + }...) } // The simplest case just boils down to a single jgt instruction, @@ -349,12 +381,6 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error) // If we're on x86 we need to add a check for x32 and if we're in // the wrong mode we jump over the section. if uint32(nativeArch) == uint32(C.C_AUDIT_ARCH_X86_64) { - // Grab the only architecture in the map. - var scmpArch libseccomp.ScmpArch - for arch := range maxSyscalls { - scmpArch = arch - } - // Generate a prefix to check the mode. switch scmpArch { case libseccomp.ArchAMD64: @@ -512,7 +538,7 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error) // Prepend the load instruction for the architecture. programTail = append([]bpf.Instruction{ - // load [4] + // load [4] (architecture) bpf.LoadAbsolute{Off: 4, Size: 4}, // NOTE: We assume sizeof(int) == 4. }, programTail...) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go index f177b7f05f2..8c12af72be9 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go @@ -113,8 +113,8 @@ func InitSeccomp(config *configs.Seccomp) (int, error) { // Convert Libcontainer Action to Libseccomp ScmpAction func getAction(act configs.Action, errnoRet *uint) (libseccomp.ScmpAction, error) { switch act { - case configs.Kill: - return libseccomp.ActKill, nil + case configs.Kill, configs.KillThread: + return libseccomp.ActKillThread, nil case configs.Errno: if errnoRet != nil { return libseccomp.ActErrno.SetReturnCode(int16(*errnoRet)), nil @@ -133,8 +133,6 @@ func getAction(act configs.Action, errnoRet *uint) (libseccomp.ScmpAction, error return libseccomp.ActLog, nil case configs.Notify: return libseccomp.ActNotify, nil - case configs.KillThread: - return libseccomp.ActKillThread, nil case configs.KillProcess: return libseccomp.ActKillProcess, nil default: diff --git a/vendor/github.com/seccomp/libseccomp-golang/.golangci.yml b/vendor/github.com/seccomp/libseccomp-golang/.golangci.yml new file mode 100644 index 00000000000..7df8aa19838 --- /dev/null +++ b/vendor/github.com/seccomp/libseccomp-golang/.golangci.yml @@ -0,0 +1,4 @@ +# For documentation, see https://golangci-lint.run/usage/configuration/ +linters: + enable: + - gofumpt diff --git a/vendor/github.com/seccomp/libseccomp-golang/.travis.yml b/vendor/github.com/seccomp/libseccomp-golang/.travis.yml deleted file mode 100644 index 5240d462280..00000000000 --- a/vendor/github.com/seccomp/libseccomp-golang/.travis.yml +++ /dev/null @@ -1,57 +0,0 @@ -# Travis CI configuration for libseccomp-golang - -# https://docs.travis-ci.com/user/reference/bionic -# https://wiki.ubuntu.com/Releases - -dist: bionic -sudo: false - -notifications: - email: - on_success: always - on_failure: always - -arch: - - amd64 - -os: - - linux - -language: go - -jobs: - include: - - name: "last libseccomp 2.5.0" - env: - - SECCOMP_VER=2.5.0 - - SECCOMP_SHA256SUM=1ffa7038d2720ad191919816db3479295a4bcca1ec14e02f672539f4983014f3 - - name: "compat libseccomp 2.4.4" - env: - - SECCOMP_VER=2.4.4 - - SECCOMP_SHA256SUM=4e79738d1ef3c9b7ca9769f1f8b8d84fc17143c2c1c432e53b9c64787e0ff3eb - - name: "compat libseccomp 2.2.1" - env: - - SECCOMP_VER=2.2.1 - - SECCOMP_SHA256SUM=0ba1789f54786c644af54cdffc9fd0dd0a8bb2b2ee153933f658855d2851a740 - -addons: - apt: - packages: - - build-essential - - astyle - - golint - - gperf - -install: - - go get -u golang.org/x/lint/golint - -# run all of the tests independently, fail if any of the tests error -script: - - wget https://github.com/seccomp/libseccomp/releases/download/v$SECCOMP_VER/libseccomp-$SECCOMP_VER.tar.gz - - echo $SECCOMP_SHA256SUM libseccomp-$SECCOMP_VER.tar.gz | sha256sum -c - - tar xf libseccomp-$SECCOMP_VER.tar.gz - - pushd libseccomp-$SECCOMP_VER && ./configure --prefix=/opt/libseccomp-$SECCOMP_VER && make && sudo make install && popd - - make check-syntax - - make lint - - PKG_CONFIG_PATH=/opt/libseccomp-$SECCOMP_VER/lib/pkgconfig LD_LIBRARY_PATH=/opt/libseccomp-$SECCOMP_VER/lib make vet - - PKG_CONFIG_PATH=/opt/libseccomp-$SECCOMP_VER/lib/pkgconfig LD_LIBRARY_PATH=/opt/libseccomp-$SECCOMP_VER/lib make test diff --git a/vendor/github.com/seccomp/libseccomp-golang/CONTRIBUTING.md b/vendor/github.com/seccomp/libseccomp-golang/CONTRIBUTING.md index d6862cbd5f9..c2fc80d5af6 100644 --- a/vendor/github.com/seccomp/libseccomp-golang/CONTRIBUTING.md +++ b/vendor/github.com/seccomp/libseccomp-golang/CONTRIBUTING.md @@ -1,31 +1,23 @@ -How to Submit Patches to the libseccomp Project +How to Submit Patches to the libseccomp-golang Project =============================================================================== https://github.com/seccomp/libseccomp-golang This document is intended to act as a guide to help you contribute to the -libseccomp project. It is not perfect, and there will always be exceptions -to the rules described here, but by following the instructions below you -should have a much easier time getting your work merged with the upstream +libseccomp-golang project. It is not perfect, and there will always be +exceptions to the rules described here, but by following the instructions below +you should have a much easier time getting your work merged with the upstream project. ## Test Your Code Using Existing Tests -There are two possible tests you can run to verify your code. The first -test is used to check the formatting and coding style of your changes, you -can run the test with the following command: - - # make check-syntax - -... if there are any problems with your changes a diff/patch will be shown -which indicates the problems and how to fix them. - -The second possible test is used to ensure the sanity of your code changes -and to test these changes against the included tests. You can run the test -with the following command: +A number of tests and lint related recipes are provided in the Makefile, if +you want to run the standard regression tests, you can execute the following: # make check -... if there are any faults or errors they will be displayed. +In order to use it, the 'golangci-lint' tool is needed, which can be found at: + +* https://github.com/golangci/golangci-lint ## Add New Tests for New Functionality diff --git a/vendor/github.com/seccomp/libseccomp-golang/Makefile b/vendor/github.com/seccomp/libseccomp-golang/Makefile index 38cfa852cd6..530f5b4adbc 100644 --- a/vendor/github.com/seccomp/libseccomp-golang/Makefile +++ b/vendor/github.com/seccomp/libseccomp-golang/Makefile @@ -4,7 +4,7 @@ all: check-build -check: vet test +check: lint test check-build: go build @@ -16,7 +16,7 @@ fix-syntax: gofmt -w . vet: - go vet -v + go vet -v ./... # Previous bugs have made the tests freeze until the timeout. Golang default # timeout for tests is 10 minutes, which is too long, considering current tests @@ -28,5 +28,4 @@ test: go test -v -timeout $(TEST_TIMEOUT) lint: - @$(if $(shell which golint),true,$(error "install golint and include it in your PATH")) - golint -set_exit_status + golangci-lint run . diff --git a/vendor/github.com/seccomp/libseccomp-golang/README.md b/vendor/github.com/seccomp/libseccomp-golang/README.md index 806a5ddf29b..6430f1c9e25 100644 --- a/vendor/github.com/seccomp/libseccomp-golang/README.md +++ b/vendor/github.com/seccomp/libseccomp-golang/README.md @@ -2,7 +2,9 @@ =============================================================================== https://github.com/seccomp/libseccomp-golang -[![Build Status](https://img.shields.io/travis/seccomp/libseccomp-golang/main.svg)](https://travis-ci.org/seccomp/libseccomp-golang) +[![Go Reference](https://pkg.go.dev/badge/github.com/seccomp/libseccomp-golang.svg)](https://pkg.go.dev/github.com/seccomp/libseccomp-golang) +[![validate](https://github.com/seccomp/libseccomp-golang/actions/workflows/validate.yml/badge.svg)](https://github.com/seccomp/libseccomp-golang/actions/workflows/validate.yml) +[![test](https://github.com/seccomp/libseccomp-golang/actions/workflows/test.yml/badge.svg)](https://github.com/seccomp/libseccomp-golang/actions/workflows/test.yml) The libseccomp library provides an easy to use, platform independent, interface to the Linux Kernel's syscall filtering mechanism. The libseccomp API is @@ -26,26 +28,14 @@ list. * https://groups.google.com/d/forum/libseccomp -Documentation is also available at: +Documentation for this package is also available at: -* https://godoc.org/github.com/seccomp/libseccomp-golang +* https://pkg.go.dev/github.com/seccomp/libseccomp-golang ## Installing the package -The libseccomp-golang bindings require at least Go v1.2.1 and GCC v4.8.4; -earlier versions may yield unpredictable results. If you meet these -requirements you can install this package using the command below: - # go get github.com/seccomp/libseccomp-golang -## Testing the Library +## Contributing -A number of tests and lint related recipes are provided in the Makefile, if -you want to run the standard regression tests, you can excute the following: - - # make check - -In order to execute the 'make lint' recipe the 'golint' tool is needed, it -can be found at: - -* https://github.com/golang/lint +See [CONTRIBUTING.md](CONTRIBUTING.md). diff --git a/vendor/github.com/seccomp/libseccomp-golang/SECURITY.md b/vendor/github.com/seccomp/libseccomp-golang/SECURITY.md new file mode 100644 index 00000000000..c448faa8e80 --- /dev/null +++ b/vendor/github.com/seccomp/libseccomp-golang/SECURITY.md @@ -0,0 +1,47 @@ +The libseccomp-golang Security Vulnerability Handling Process +=============================================================================== +https://github.com/seccomp/libseccomp-golang + +This document document attempts to describe the processes through which +sensitive security relevant bugs can be responsibly disclosed to the +libseccomp-golang project and how the project maintainers should handle these +reports. Just like the other libseccomp-golang process documents, this +document should be treated as a guiding document and not a hard, unyielding set +of regulations; the bug reporters and project maintainers are encouraged to +work together to address the issues as best they can, in a manner which works +best for all parties involved. + +### Reporting Problems + +Problems with the libseccomp-golang library that are not suitable for immediate +public disclosure should be emailed to the current libseccomp-golang +maintainers, the list is below. We typically request at most a 90 day time +period to address the issue before it is made public, but we will make every +effort to address the issue as quickly as possible and shorten the disclosure +window. + +* Paul Moore, paul@paul-moore.com +* Tom Hromatka, tom.hromatka@oracle.com + +### Resolving Sensitive Security Issues + +Upon disclosure of a bug, the maintainers should work together to investigate +the problem and decide on a solution. In order to prevent an early disclosure +of the problem, those working on the solution should do so privately and +outside of the traditional libseccomp-golang development practices. One +possible solution to this is to leverage the GitHub "Security" functionality to +create a private development fork that can be shared among the maintainers, and +optionally the reporter. A placeholder GitHub issue may be created, but +details should remain extremely limited until such time as the problem has been +fixed and responsibly disclosed. If a CVE, or other tag, has been assigned to +the problem, the GitHub issue title should include the vulnerability tag once +the problem has been disclosed. + +### Public Disclosure + +Whenever possible, responsible reporting and patching practices should be +followed, including notification to the linux-distros and oss-security mailing +lists. + +* https://oss-security.openwall.org/wiki/mailing-lists/distros +* https://oss-security.openwall.org/wiki/mailing-lists/oss-security diff --git a/vendor/github.com/seccomp/libseccomp-golang/seccomp.go b/vendor/github.com/seccomp/libseccomp-golang/seccomp.go index e9b92e2219a..8dad12fdbb9 100644 --- a/vendor/github.com/seccomp/libseccomp-golang/seccomp.go +++ b/vendor/github.com/seccomp/libseccomp-golang/seccomp.go @@ -1,5 +1,3 @@ -// +build linux - // Public API specification for libseccomp Go bindings // Contains public API for the bindings @@ -18,48 +16,36 @@ import ( "unsafe" ) -// C wrapping code - -// To compile libseccomp-golang against a specific version of libseccomp: -// cd ../libseccomp && mkdir -p prefix -// ./configure --prefix=$PWD/prefix && make && make install -// cd ../libseccomp-golang -// PKG_CONFIG_PATH=$PWD/../libseccomp/prefix/lib/pkgconfig/ make -// LD_PRELOAD=$PWD/../libseccomp/prefix/lib/libseccomp.so.2.5.0 PKG_CONFIG_PATH=$PWD/../libseccomp/prefix/lib/pkgconfig/ make test - -// #cgo pkg-config: libseccomp // #include // #include import "C" // Exported types -// VersionError denotes that the system libseccomp version is incompatible -// with this package. +// VersionError represents an error when either the system libseccomp version +// or the kernel version is too old to perform the operation requested. type VersionError struct { - message string - minimum string + op string // operation that failed or would fail + major, minor, micro uint // minimally required libseccomp version + curAPI, minAPI uint // current and minimally required API versions } func init() { // This forces the cgo libseccomp to initialize its internal API support state, // which is necessary on older versions of libseccomp in order to work // correctly. - GetAPI() + _, _ = getAPI() } func (e VersionError) Error() string { - messageStr := "" - if e.message != "" { - messageStr = e.message + ": " + if e.minAPI != 0 { + return fmt.Sprintf("%s requires libseccomp >= %d.%d.%d and API level >= %d "+ + "(current version: %d.%d.%d, API level: %d)", + e.op, e.major, e.minor, e.micro, e.minAPI, + verMajor, verMinor, verMicro, e.curAPI) } - minimumStr := "" - if e.minimum != "" { - minimumStr = e.minimum - } else { - minimumStr = "2.2.0" - } - return fmt.Sprintf("Libseccomp version too low: %sminimum supported is %s: detected %d.%d.%d", messageStr, minimumStr, verMajor, verMinor, verMicro) + return fmt.Sprintf("%s requires libseccomp >= %d.%d.%d (current version: %d.%d.%d)", + e.op, e.major, e.minor, e.micro, verMajor, verMinor, verMicro) } // ScmpArch represents a CPU architecture. Seccomp can restrict syscalls on a @@ -148,44 +134,46 @@ const ( // variables are invalid ArchInvalid ScmpArch = iota // ArchNative is the native architecture of the kernel - ArchNative ScmpArch = iota + ArchNative // ArchX86 represents 32-bit x86 syscalls - ArchX86 ScmpArch = iota + ArchX86 // ArchAMD64 represents 64-bit x86-64 syscalls - ArchAMD64 ScmpArch = iota + ArchAMD64 // ArchX32 represents 64-bit x86-64 syscalls (32-bit pointers) - ArchX32 ScmpArch = iota + ArchX32 // ArchARM represents 32-bit ARM syscalls - ArchARM ScmpArch = iota + ArchARM // ArchARM64 represents 64-bit ARM syscalls - ArchARM64 ScmpArch = iota + ArchARM64 // ArchMIPS represents 32-bit MIPS syscalls - ArchMIPS ScmpArch = iota + ArchMIPS // ArchMIPS64 represents 64-bit MIPS syscalls - ArchMIPS64 ScmpArch = iota + ArchMIPS64 // ArchMIPS64N32 represents 64-bit MIPS syscalls (32-bit pointers) - ArchMIPS64N32 ScmpArch = iota + ArchMIPS64N32 // ArchMIPSEL represents 32-bit MIPS syscalls (little endian) - ArchMIPSEL ScmpArch = iota + ArchMIPSEL // ArchMIPSEL64 represents 64-bit MIPS syscalls (little endian) - ArchMIPSEL64 ScmpArch = iota + ArchMIPSEL64 // ArchMIPSEL64N32 represents 64-bit MIPS syscalls (little endian, // 32-bit pointers) - ArchMIPSEL64N32 ScmpArch = iota + ArchMIPSEL64N32 // ArchPPC represents 32-bit POWERPC syscalls - ArchPPC ScmpArch = iota + ArchPPC // ArchPPC64 represents 64-bit POWER syscalls (big endian) - ArchPPC64 ScmpArch = iota + ArchPPC64 // ArchPPC64LE represents 64-bit POWER syscalls (little endian) - ArchPPC64LE ScmpArch = iota + ArchPPC64LE // ArchS390 represents 31-bit System z/390 syscalls - ArchS390 ScmpArch = iota + ArchS390 // ArchS390X represents 64-bit System z/390 syscalls - ArchS390X ScmpArch = iota + ArchS390X // ArchPARISC represents 32-bit PA-RISC - ArchPARISC ScmpArch = iota + ArchPARISC // ArchPARISC64 represents 64-bit PA-RISC - ArchPARISC64 ScmpArch = iota + ArchPARISC64 + // ArchRISCV64 represents RISCV64 + ArchRISCV64 ) const ( @@ -194,34 +182,36 @@ const ( // ActInvalid is a placeholder to ensure uninitialized ScmpAction // variables are invalid ActInvalid ScmpAction = iota - // ActKill kills the thread that violated the rule. It is the same as ActKillThread. + // ActKillThread kills the thread that violated the rule. // All other threads from the same thread group will continue to execute. - ActKill ScmpAction = iota + ActKillThread // ActTrap throws SIGSYS - ActTrap ScmpAction = iota + ActTrap // ActNotify triggers a userspace notification. This action is only usable when // libseccomp API level 6 or higher is supported. - ActNotify ScmpAction = iota + ActNotify // ActErrno causes the syscall to return a negative error code. This // code can be set with the SetReturnCode method - ActErrno ScmpAction = iota + ActErrno // ActTrace causes the syscall to notify tracing processes with the // given error code. This code can be set with the SetReturnCode method - ActTrace ScmpAction = iota + ActTrace // ActAllow permits the syscall to continue execution - ActAllow ScmpAction = iota + ActAllow // ActLog permits the syscall to continue execution after logging it. // This action is only usable when libseccomp API level 3 or higher is // supported. - ActLog ScmpAction = iota - // ActKillThread kills the thread that violated the rule. It is the same as ActKill. - // All other threads from the same thread group will continue to execute. - ActKillThread ScmpAction = iota + ActLog // ActKillProcess kills the process that violated the rule. // All threads in the thread group are also terminated. // This action is only usable when libseccomp API level 3 or higher is // supported. - ActKillProcess ScmpAction = iota + ActKillProcess + // ActKill kills the thread that violated the rule. + // All other threads from the same thread group will continue to execute. + // + // Deprecated: use ActKillThread + ActKill = ActKillThread ) const ( @@ -234,36 +224,35 @@ const ( CompareInvalid ScmpCompareOp = iota // CompareNotEqual returns true if the argument is not equal to the // given value - CompareNotEqual ScmpCompareOp = iota + CompareNotEqual // CompareLess returns true if the argument is less than the given value - CompareLess ScmpCompareOp = iota + CompareLess // CompareLessOrEqual returns true if the argument is less than or equal // to the given value - CompareLessOrEqual ScmpCompareOp = iota + CompareLessOrEqual // CompareEqual returns true if the argument is equal to the given value - CompareEqual ScmpCompareOp = iota + CompareEqual // CompareGreaterEqual returns true if the argument is greater than or // equal to the given value - CompareGreaterEqual ScmpCompareOp = iota + CompareGreaterEqual // CompareGreater returns true if the argument is greater than the given // value - CompareGreater ScmpCompareOp = iota - // CompareMaskedEqual returns true if the argument is equal to the given - // value, when masked (bitwise &) against the second given value - CompareMaskedEqual ScmpCompareOp = iota + CompareGreater + // CompareMaskedEqual returns true if the masked argument value is + // equal to the masked datum value. Mask is the first argument, and + // datum is the second one. + CompareMaskedEqual ) -var ( - // ErrSyscallDoesNotExist represents an error condition where - // libseccomp is unable to resolve the syscall - ErrSyscallDoesNotExist = fmt.Errorf("could not resolve syscall name") -) +// ErrSyscallDoesNotExist represents an error condition where +// libseccomp is unable to resolve the syscall +var ErrSyscallDoesNotExist = fmt.Errorf("could not resolve syscall name") const ( // Userspace notification response flags // NotifRespFlagContinue tells the kernel to continue executing the system - // call that triggered the notification. Must only be used when the notication + // call that triggered the notification. Must only be used when the notification // response's error is 0. NotifRespFlagContinue uint32 = 1 ) @@ -314,6 +303,8 @@ func GetArchFromString(arch string) (ScmpArch, error) { return ArchPARISC, nil case "parisc64": return ArchPARISC64, nil + case "riscv64": + return ArchRISCV64, nil default: return ArchInvalid, fmt.Errorf("cannot convert unrecognized string %q", arch) } @@ -358,6 +349,8 @@ func (a ScmpArch) String() string { return "parisc" case ArchPARISC64: return "parisc64" + case ArchRISCV64: + return "riscv64" case ArchNative: return "native" case ArchInvalid: @@ -394,7 +387,7 @@ func (a ScmpCompareOp) String() string { // String returns a string representation of a seccomp match action func (a ScmpAction) String() string { switch a & 0xFFFF { - case ActKill, ActKillThread: + case ActKillThread: return "Action: Kill thread" case ActKillProcess: return "Action: Kill process" @@ -556,8 +549,8 @@ func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCo return condStruct, err } - if comparison == CompareInvalid { - return condStruct, fmt.Errorf("invalid comparison operator") + if err := sanitizeCompareOp(comparison); err != nil { + return condStruct, err } else if arg > 5 { return condStruct, fmt.Errorf("syscalls only have up to 6 arguments (%d given)", arg) } else if len(values) > 2 { @@ -874,10 +867,8 @@ func (f *ScmpFilter) GetNoNewPrivsBit() (bool, error) { func (f *ScmpFilter) GetLogBit() (bool, error) { log, err := f.getFilterAttr(filterAttrLog) if err != nil { - // Ignore error, if not supported returns apiLevel == 0 - apiLevel, _ := GetAPI() - if apiLevel < 3 { - return false, fmt.Errorf("getting the log bit is only supported in libseccomp 2.4.0 and newer with API level 3 or higher") + if e := checkAPI("GetLogBit", 3, 2, 4, 0); e != nil { + err = e } return false, err @@ -899,9 +890,8 @@ func (f *ScmpFilter) GetLogBit() (bool, error) { func (f *ScmpFilter) GetSSB() (bool, error) { ssb, err := f.getFilterAttr(filterAttrSSB) if err != nil { - api, apiErr := getAPI() - if (apiErr != nil && api == 0) || (apiErr == nil && api < 4) { - return false, fmt.Errorf("getting the SSB flag is only supported in libseccomp 2.5.0 and newer with API level 4 or higher") + if e := checkAPI("GetSSB", 4, 2, 5, 0); e != nil { + err = e } return false, err @@ -914,6 +904,42 @@ func (f *ScmpFilter) GetSSB() (bool, error) { return true, nil } +// GetOptimize returns the current optimization level of the filter, +// or an error if an issue was encountered retrieving the value. +// See SetOptimize for more details. +func (f *ScmpFilter) GetOptimize() (int, error) { + level, err := f.getFilterAttr(filterAttrOptimize) + if err != nil { + if e := checkAPI("GetOptimize", 4, 2, 5, 0); e != nil { + err = e + } + + return 0, err + } + + return int(level), nil +} + +// GetRawRC returns the current state of RawRC flag, or an error +// if an issue was encountered retrieving the value. +// See SetRawRC for more details. +func (f *ScmpFilter) GetRawRC() (bool, error) { + rawrc, err := f.getFilterAttr(filterAttrRawRC) + if err != nil { + if e := checkAPI("GetRawRC", 4, 2, 5, 0); e != nil { + err = e + } + + return false, err + } + + if rawrc == 0 { + return false, nil + } + + return true, nil +} + // SetBadArchAction sets the default action taken on a syscall for an // architecture not in the filter, or an error if an issue was encountered // setting the value. @@ -953,10 +979,8 @@ func (f *ScmpFilter) SetLogBit(state bool) error { err := f.setFilterAttr(filterAttrLog, toSet) if err != nil { - // Ignore error, if not supported returns apiLevel == 0 - apiLevel, _ := GetAPI() - if apiLevel < 3 { - return fmt.Errorf("setting the log bit is only supported in libseccomp 2.4.0 and newer with API level 3 or higher") + if e := checkAPI("SetLogBit", 3, 2, 4, 0); e != nil { + err = e } } @@ -976,9 +1000,52 @@ func (f *ScmpFilter) SetSSB(state bool) error { err := f.setFilterAttr(filterAttrSSB, toSet) if err != nil { - api, apiErr := getAPI() - if (apiErr != nil && api == 0) || (apiErr == nil && api < 4) { - return fmt.Errorf("setting the SSB flag is only supported in libseccomp 2.5.0 and newer with API level 4 or higher") + if e := checkAPI("SetSSB", 4, 2, 5, 0); e != nil { + err = e + } + } + + return err +} + +// SetOptimize sets optimization level of the seccomp filter. By default +// libseccomp generates a set of sequential "if" statements for each rule in +// the filter. SetSyscallPriority can be used to prioritize the order for the +// default cause. The binary tree optimization sorts by syscall numbers and +// generates consistent O(log n) filter traversal for every rule in the filter. +// The binary tree may be advantageous for large filters. Note that +// SetSyscallPriority is ignored when level == 2. +// +// The different optimization levels are: +// 0: Reserved value, not currently used. +// 1: Rules sorted by priority and complexity (DEFAULT). +// 2: Binary tree sorted by syscall number. +func (f *ScmpFilter) SetOptimize(level int) error { + cLevel := C.uint32_t(level) + + err := f.setFilterAttr(filterAttrOptimize, cLevel) + if err != nil { + if e := checkAPI("SetOptimize", 4, 2, 5, 0); e != nil { + err = e + } + } + + return err +} + +// SetRawRC sets whether libseccomp should pass system error codes back to the +// caller, instead of the default ECANCELED. Defaults to false. +func (f *ScmpFilter) SetRawRC(state bool) error { + var toSet C.uint32_t = 0x0 + + if state { + toSet = 0x1 + } + + err := f.setFilterAttr(filterAttrRawRC, toSet) + if err != nil { + if e := checkAPI("SetRawRC", 4, 2, 5, 0); e != nil { + err = e } } @@ -1029,9 +1096,6 @@ func (f *ScmpFilter) AddRuleExact(call ScmpSyscall, action ScmpAction) error { // AddRuleConditional adds a single rule for a conditional action on a syscall. // Returns an error if an issue was encountered adding the rule. // All conditions must match for the rule to match. -// There is a bug in library versions below v2.2.1 which can, in some cases, -// cause conditions to be lost when more than one are used. Consequently, -// AddRuleConditional is disabled on library versions lower than v2.2.1 func (f *ScmpFilter) AddRuleConditional(call ScmpSyscall, action ScmpAction, conds []ScmpCondition) error { return f.addRuleGeneric(call, action, false, conds) } @@ -1043,9 +1107,6 @@ func (f *ScmpFilter) AddRuleConditional(call ScmpSyscall, action ScmpAction, con // The rule will function exactly as described, but it may not function identically // (or be able to be applied to) all architectures. // Returns an error if an issue was encountered adding the rule. -// There is a bug in library versions below v2.2.1 which can, in some cases, -// cause conditions to be lost when more than one are used. Consequently, -// AddRuleConditionalExact is disabled on library versions lower than v2.2.1 func (f *ScmpFilter) AddRuleConditionalExact(call ScmpSyscall, action ScmpAction, conds []ScmpCondition) error { return f.addRuleGeneric(call, action, true, conds) } diff --git a/vendor/github.com/seccomp/libseccomp-golang/seccomp_internal.go b/vendor/github.com/seccomp/libseccomp-golang/seccomp_internal.go index 8dc7b296f3b..df4dfb7eba8 100644 --- a/vendor/github.com/seccomp/libseccomp-golang/seccomp_internal.go +++ b/vendor/github.com/seccomp/libseccomp-golang/seccomp_internal.go @@ -1,11 +1,10 @@ -// +build linux - // Internal functions for libseccomp Go bindings // No exported functions package seccomp import ( + "errors" "fmt" "syscall" ) @@ -27,10 +26,10 @@ import ( #include #include -#if SCMP_VER_MAJOR < 2 -#error Minimum supported version of Libseccomp is v2.2.0 -#elif SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 2 -#error Minimum supported version of Libseccomp is v2.2.0 +#if (SCMP_VER_MAJOR < 2) || \ + (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 3) || \ + (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR == 3 && SCMP_VER_MICRO < 1) +#error This package requires libseccomp >= v2.3.1 #endif #define ARCH_BAD ~0 @@ -65,6 +64,10 @@ const uint32_t C_ARCH_BAD = ARCH_BAD; #define SCMP_ARCH_PARISC64 ARCH_BAD #endif +#ifndef SCMP_ARCH_RISCV64 +#define SCMP_ARCH_RISCV64 ARCH_BAD +#endif + const uint32_t C_ARCH_NATIVE = SCMP_ARCH_NATIVE; const uint32_t C_ARCH_X86 = SCMP_ARCH_X86; const uint32_t C_ARCH_X86_64 = SCMP_ARCH_X86_64; @@ -84,6 +87,7 @@ const uint32_t C_ARCH_S390 = SCMP_ARCH_S390; const uint32_t C_ARCH_S390X = SCMP_ARCH_S390X; const uint32_t C_ARCH_PARISC = SCMP_ARCH_PARISC; const uint32_t C_ARCH_PARISC64 = SCMP_ARCH_PARISC64; +const uint32_t C_ARCH_RISCV64 = SCMP_ARCH_RISCV64; #ifndef SCMP_ACT_LOG #define SCMP_ACT_LOG 0x7ffc0000U @@ -113,20 +117,25 @@ const uint32_t C_ACT_NOTIFY = SCMP_ACT_NOTIFY; // The libseccomp SCMP_FLTATR_CTL_LOG member of the scmp_filter_attr enum was // added in v2.4.0 -#if (SCMP_VER_MAJOR < 2) || \ - (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 4) +#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 4 #define SCMP_FLTATR_CTL_LOG _SCMP_FLTATR_MIN #endif + +// The following SCMP_FLTATR_* were added in libseccomp v2.5.0. #if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 5 -#define SCMP_FLTATR_CTL_SSB _SCMP_FLTATR_MIN +#define SCMP_FLTATR_CTL_SSB _SCMP_FLTATR_MIN +#define SCMP_FLTATR_CTL_OPTIMIZE _SCMP_FLTATR_MIN +#define SCMP_FLTATR_API_SYSRAWRC _SCMP_FLTATR_MIN #endif -const uint32_t C_ATTRIBUTE_DEFAULT = (uint32_t)SCMP_FLTATR_ACT_DEFAULT; -const uint32_t C_ATTRIBUTE_BADARCH = (uint32_t)SCMP_FLTATR_ACT_BADARCH; -const uint32_t C_ATTRIBUTE_NNP = (uint32_t)SCMP_FLTATR_CTL_NNP; -const uint32_t C_ATTRIBUTE_TSYNC = (uint32_t)SCMP_FLTATR_CTL_TSYNC; -const uint32_t C_ATTRIBUTE_LOG = (uint32_t)SCMP_FLTATR_CTL_LOG; -const uint32_t C_ATTRIBUTE_SSB = (uint32_t)SCMP_FLTATR_CTL_SSB; +const uint32_t C_ATTRIBUTE_DEFAULT = (uint32_t)SCMP_FLTATR_ACT_DEFAULT; +const uint32_t C_ATTRIBUTE_BADARCH = (uint32_t)SCMP_FLTATR_ACT_BADARCH; +const uint32_t C_ATTRIBUTE_NNP = (uint32_t)SCMP_FLTATR_CTL_NNP; +const uint32_t C_ATTRIBUTE_TSYNC = (uint32_t)SCMP_FLTATR_CTL_TSYNC; +const uint32_t C_ATTRIBUTE_LOG = (uint32_t)SCMP_FLTATR_CTL_LOG; +const uint32_t C_ATTRIBUTE_SSB = (uint32_t)SCMP_FLTATR_CTL_SSB; +const uint32_t C_ATTRIBUTE_OPTIMIZE = (uint32_t)SCMP_FLTATR_CTL_OPTIMIZE; +const uint32_t C_ATTRIBUTE_SYSRAWRC = (uint32_t)SCMP_FLTATR_API_SYSRAWRC; const int C_CMP_NE = (int)SCMP_CMP_NE; const int C_CMP_LT = (int)SCMP_CMP_LT; @@ -173,8 +182,7 @@ unsigned int get_micro_version() #endif // The libseccomp API level functions were added in v2.4.0 -#if (SCMP_VER_MAJOR < 2) || \ - (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 4) +#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 4 const unsigned int seccomp_api_get(void) { // libseccomp-golang requires libseccomp v2.2.0, at a minimum, which @@ -217,8 +225,7 @@ void add_struct_arg_cmp( } // The seccomp notify API functions were added in v2.5.0 -#if (SCMP_VER_MAJOR < 2) || \ - (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 5) +#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 5 struct seccomp_data { int nr; @@ -270,11 +277,13 @@ type scmpFilterAttr uint32 const ( filterAttrActDefault scmpFilterAttr = iota - filterAttrActBadArch scmpFilterAttr = iota - filterAttrNNP scmpFilterAttr = iota - filterAttrTsync scmpFilterAttr = iota - filterAttrLog scmpFilterAttr = iota - filterAttrSSB scmpFilterAttr = iota + filterAttrActBadArch + filterAttrNNP + filterAttrTsync + filterAttrLog + filterAttrSSB + filterAttrOptimize + filterAttrRawRC ) const ( @@ -282,9 +291,9 @@ const ( scmpError C.int = -1 // Comparison boundaries to check for architecture validity archStart ScmpArch = ArchNative - archEnd ScmpArch = ArchPARISC64 + archEnd ScmpArch = ArchRISCV64 // Comparison boundaries to check for action validity - actionStart ScmpAction = ActKill + actionStart ScmpAction = ActKillThread actionEnd ScmpAction = ActKillProcess // Comparison boundaries to check for comparison operator validity compareOpStart ScmpCompareOp = CompareNotEqual @@ -292,8 +301,9 @@ const ( ) var ( - // Error thrown on bad filter context - errBadFilter = fmt.Errorf("filter is invalid or uninitialized") + // errBadFilter is thrown on bad filter context. + errBadFilter = errors.New("filter is invalid or uninitialized") + errDefAction = errors.New("requested action matches default action of filter") // Constants representing library major, minor, and micro versions verMajor = uint(C.get_major_version()) verMinor = uint(C.get_minor_version()) @@ -302,19 +312,28 @@ var ( // Nonexported functions -// Check if library version is greater than or equal to the given one -func checkVersionAbove(major, minor, micro uint) bool { - return (verMajor > major) || +// checkVersion returns an error if the libseccomp version being used +// is less than the one specified by major, minor, and micro arguments. +// Argument op is an arbitrary non-empty operation description, which +// is used as a part of the error message returned. +// +// Most users should use checkAPI instead. +func checkVersion(op string, major, minor, micro uint) error { + if (verMajor > major) || (verMajor == major && verMinor > minor) || - (verMajor == major && verMinor == minor && verMicro >= micro) + (verMajor == major && verMinor == minor && verMicro >= micro) { + return nil + } + return &VersionError{ + op: op, + major: major, + minor: minor, + micro: micro, + } } -// Ensure that the library is supported, i.e. >= 2.2.0. func ensureSupportedVersion() error { - if !checkVersionAbove(2, 2, 0) { - return VersionError{} - } - return nil + return checkVersion("seccomp", 2, 3, 1) } // Get the API level @@ -406,8 +425,10 @@ func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact b switch e := errRc(retCode); e { case syscall.EFAULT: return fmt.Errorf("unrecognized syscall %#x", int32(call)) - case syscall.EPERM: - return fmt.Errorf("requested action matches default action of filter") + // libseccomp >= v2.5.0 returns EACCES, older versions return EPERM. + // TODO: remove EPERM once libseccomp < v2.5.0 is not supported. + case syscall.EPERM, syscall.EACCES: + return errDefAction case syscall.EINVAL: return fmt.Errorf("two checks on same syscall argument") default: @@ -432,14 +453,6 @@ func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact b return err } } else { - // We don't support conditional filtering in library version v2.1 - if !checkVersionAbove(2, 2, 1) { - return VersionError{ - message: "conditional filtering is not supported", - minimum: "2.2.1", - } - } - argsArr := C.make_arg_cmp_array(C.uint(len(conds))) if argsArr == nil { return fmt.Errorf("error allocating memory for conditions") @@ -536,6 +549,8 @@ func archFromNative(a C.uint32_t) (ScmpArch, error) { return ArchPARISC, nil case C.C_ARCH_PARISC64: return ArchPARISC64, nil + case C.C_ARCH_RISCV64: + return ArchRISCV64, nil default: return 0x0, fmt.Errorf("unrecognized architecture %#x", uint32(a)) } @@ -580,6 +595,8 @@ func (a ScmpArch) toNative() C.uint32_t { return C.C_ARCH_PARISC case ArchPARISC64: return C.C_ARCH_PARISC64 + case ArchRISCV64: + return C.C_ARCH_RISCV64 case ArchNative: return C.C_ARCH_NATIVE default: @@ -612,8 +629,6 @@ func (a ScmpCompareOp) toNative() C.int { func actionFromNative(a C.uint32_t) (ScmpAction, error) { aTmp := a & 0xFFFF switch a & 0xFFFF0000 { - case C.C_ACT_KILL: - return ActKill, nil case C.C_ACT_KILL_PROCESS: return ActKillProcess, nil case C.C_ACT_KILL_THREAD: @@ -638,8 +653,6 @@ func actionFromNative(a C.uint32_t) (ScmpAction, error) { // Only use with sanitized actions, no error handling func (a ScmpAction) toNative() C.uint32_t { switch a & 0xFFFF { - case ActKill: - return C.C_ACT_KILL case ActKillProcess: return C.C_ACT_KILL_PROCESS case ActKillThread: @@ -676,15 +689,15 @@ func (a scmpFilterAttr) toNative() uint32 { return uint32(C.C_ATTRIBUTE_LOG) case filterAttrSSB: return uint32(C.C_ATTRIBUTE_SSB) + case filterAttrOptimize: + return uint32(C.C_ATTRIBUTE_OPTIMIZE) + case filterAttrRawRC: + return uint32(C.C_ATTRIBUTE_SYSRAWRC) default: return 0x0 } } -func (a ScmpSyscall) toNative() C.uint32_t { - return C.uint32_t(a) -} - func syscallFromNative(a C.int) ScmpSyscall { return ScmpSyscall(a) } @@ -724,9 +737,34 @@ func (scmpResp *ScmpNotifResp) toNative(resp *C.struct_seccomp_notif_resp) { resp.flags = C.__u32(scmpResp.Flags) } +// checkAPI checks that both the API level and the seccomp version is equal to +// or greater than the specified minLevel and major, minor, micro, +// respectively, and returns an error otherwise. Argument op is an arbitrary +// non-empty operation description, used as a part of the error message +// returned. +func checkAPI(op string, minLevel uint, major, minor, micro uint) error { + // Ignore error from getAPI, as it returns level == 0 in case of error. + level, _ := getAPI() + if level >= minLevel { + return checkVersion(op, major, minor, micro) + } + return &VersionError{ + op: op, + curAPI: level, + minAPI: minLevel, + major: major, + minor: minor, + micro: micro, + } +} + // Userspace Notification API // Calls to C.seccomp_notify* hidden from seccomp.go +func notifSupported() error { + return checkAPI("seccomp notification", 6, 2, 5, 0) +} + func (f *ScmpFilter) getNotifFd() (ScmpFd, error) { f.lock.Lock() defer f.lock.Unlock() @@ -734,11 +772,8 @@ func (f *ScmpFilter) getNotifFd() (ScmpFd, error) { if !f.valid { return -1, errBadFilter } - - // Ignore error, if not supported returns apiLevel == 0 - apiLevel, _ := GetAPI() - if apiLevel < 6 { - return -1, fmt.Errorf("seccomp notification requires API level >= 6; current level = %d", apiLevel) + if err := notifSupported(); err != nil { + return -1, err } fd := C.seccomp_notify_fd(f.filterCtx) @@ -750,10 +785,8 @@ func notifReceive(fd ScmpFd) (*ScmpNotifReq, error) { var req *C.struct_seccomp_notif var resp *C.struct_seccomp_notif_resp - // Ignore error, if not supported returns apiLevel == 0 - apiLevel, _ := GetAPI() - if apiLevel < 6 { - return nil, fmt.Errorf("seccomp notification requires API level >= 6; current level = %d", apiLevel) + if err := notifSupported(); err != nil { + return nil, err } // we only use the request here; the response is unused @@ -789,13 +822,11 @@ func notifRespond(fd ScmpFd, scmpResp *ScmpNotifResp) error { var req *C.struct_seccomp_notif var resp *C.struct_seccomp_notif_resp - // Ignore error, if not supported returns apiLevel == 0 - apiLevel, _ := GetAPI() - if apiLevel < 6 { - return fmt.Errorf("seccomp notification requires API level >= 6; current level = %d", apiLevel) + if err := notifSupported(); err != nil { + return err } - // we only use the reponse here; the request is discarded + // we only use the response here; the request is discarded if retCode := C.seccomp_notify_alloc(&req, &resp); retCode != 0 { return errRc(retCode) } @@ -827,10 +858,8 @@ func notifRespond(fd ScmpFd, scmpResp *ScmpNotifResp) error { } func notifIDValid(fd ScmpFd, id uint64) error { - // Ignore error, if not supported returns apiLevel == 0 - apiLevel, _ := GetAPI() - if apiLevel < 6 { - return fmt.Errorf("seccomp notification requires API level >= 6; current level = %d", apiLevel) + if err := notifSupported(); err != nil { + return err } for { diff --git a/vendor/modules.txt b/vendor/modules.txt index 9990220c6c8..4a9845b32a9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -668,7 +668,7 @@ github.com/onsi/gomega/types # github.com/opencontainers/go-digest v1.0.0 => github.com/opencontainers/go-digest v1.0.0 ## explicit; go 1.13 github.com/opencontainers/go-digest -# github.com/opencontainers/runc v1.1.1 => github.com/opencontainers/runc v1.1.1 +# github.com/opencontainers/runc v1.1.3 => github.com/opencontainers/runc v1.1.3 ## explicit; go 1.16 github.com/opencontainers/runc/libcontainer github.com/opencontainers/runc/libcontainer/apparmor @@ -752,7 +752,7 @@ github.com/russross/blackfriday # github.com/russross/blackfriday/v2 v2.1.0 => github.com/russross/blackfriday/v2 v2.1.0 ## explicit github.com/russross/blackfriday/v2 -# github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921 => github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921 +# github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 => github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 ## explicit; go 1.14 github.com/seccomp/libseccomp-golang # github.com/sirupsen/logrus v1.8.1 => github.com/sirupsen/logrus v1.8.1 @@ -2738,7 +2738,7 @@ sigs.k8s.io/yaml # github.com/onsi/gomega => github.com/onsi/gomega v1.10.1 # github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0 # github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.2 -# github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1 +# github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.3 # github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 # github.com/opencontainers/selinux => github.com/opencontainers/selinux v1.10.0 # github.com/opentracing/opentracing-go => github.com/opentracing/opentracing-go v1.1.0 @@ -2759,7 +2759,7 @@ sigs.k8s.io/yaml # github.com/rubiojr/go-vhd => github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021 # github.com/russross/blackfriday => github.com/russross/blackfriday v1.5.2 # github.com/russross/blackfriday/v2 => github.com/russross/blackfriday/v2 v2.1.0 -# github.com/seccomp/libseccomp-golang => github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921 +# github.com/seccomp/libseccomp-golang => github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 # github.com/sergi/go-diff => github.com/sergi/go-diff v1.1.0 # github.com/sirupsen/logrus => github.com/sirupsen/logrus v1.8.1 # github.com/smartystreets/assertions => github.com/smartystreets/assertions v1.1.0