From 940cd91305ed184990dc0f91e6e7e85d33a5ae5e Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Mon, 15 Jul 2024 23:50:56 -0700 Subject: [PATCH] systrap: don't fail if seccomp_unotify isn't supported Fixes #10633 PiperOrigin-RevId: 652717946 --- pkg/sentry/platform/systrap/subprocess.go | 15 +++++++++++++++ pkg/sentry/platform/systrap/syscall_thread.go | 13 ++++++++----- pkg/sentry/platform/systrap/systrap.go | 2 ++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/pkg/sentry/platform/systrap/subprocess.go b/pkg/sentry/platform/systrap/subprocess.go index d3ef17d76..11f08edba 100644 --- a/pkg/sentry/platform/systrap/subprocess.go +++ b/pkg/sentry/platform/systrap/subprocess.go @@ -178,6 +178,21 @@ type subprocess struct { dead atomicbitops.Bool } +var seccompNotifyIsSupported = false + +func initSeccompNotify() { + _, _, errno := unix.Syscall(seccomp.SYS_SECCOMP, linux.SECCOMP_SET_MODE_FILTER, linux.SECCOMP_FILTER_FLAG_NEW_LISTENER, 0) + switch errno { + case unix.EFAULT: + // seccomp unotify is supported. + case unix.EINVAL: + log.Warningf("Seccomp user-space notification mechanism isn't " + + "supported by the kernel (available since Linux 5.0).") + default: + panic(fmt.Sprintf("seccomp returns unexpected code: %d", errno)) + } +} + func (s *subprocess) initSyscallThread(ptraceThread *thread, seccompNotify bool) error { s.syscallThreadMu.Lock() defer s.syscallThreadMu.Unlock() diff --git a/pkg/sentry/platform/systrap/syscall_thread.go b/pkg/sentry/platform/systrap/syscall_thread.go index d4fce702b..0ff1accf8 100644 --- a/pkg/sentry/platform/systrap/syscall_thread.go +++ b/pkg/sentry/platform/systrap/syscall_thread.go @@ -97,8 +97,11 @@ func (t *syscallThread) init(seccompNotify bool) error { return err } - if seccompNotify { - t.seccompNotify = t.installSeccompNotify() + if seccompNotify && seccompNotifyIsSupported { + if t.seccompNotify, err = t.installSeccompNotify(); err != nil { + t.destroy() + return fmt.Errorf("failed to install seccomp notify rules: %w", err) + } } // Map the stack into the sentry. @@ -142,19 +145,19 @@ func (t *syscallThread) destroy() { t.subproc.sysmsgStackPool.Put(t.thread.sysmsgStackID) } -func (t *syscallThread) installSeccompNotify() *os.File { +func (t *syscallThread) installSeccompNotify() (*os.File, error) { fd, err := t.thread.syscallIgnoreInterrupt(&t.thread.initRegs, seccomp.SYS_SECCOMP, arch.SyscallArgument{Value: uintptr(linux.SECCOMP_SET_MODE_FILTER)}, arch.SyscallArgument{Value: uintptr(linux.SECCOMP_FILTER_FLAG_NEW_LISTENER)}, arch.SyscallArgument{Value: stubSyscallRules}) if err != nil { - panic(fmt.Sprintf("seccomp failed: %v", err)) + return nil, err } _, _, errno := unix.RawSyscall(unix.SYS_IOCTL, fd, linux.SECCOMP_IOCTL_NOTIF_SET_FLAGS, linux.SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP) if errno != 0 { t.thread.Debugf("failed to set SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP") } - return os.NewFile(fd, "seccomp_notify") + return os.NewFile(fd, "seccomp_notify"), nil } // mapMessageIntoStub maps the syscall message into the stub process address space. diff --git a/pkg/sentry/platform/systrap/systrap.go b/pkg/sentry/platform/systrap/systrap.go index 5da730e76..c9570d017 100644 --- a/pkg/sentry/platform/systrap/systrap.go +++ b/pkg/sentry/platform/systrap/systrap.go @@ -350,6 +350,8 @@ func New() (*Systrap, error) { globalPool.source = source initSysmsgThreadPriority() + + initSeccompNotify() }) latencyMonitoring.Do(func() {