mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Allow Sentry to kill itself even when it is the init process
PiperOrigin-RevId: 733399678
This commit is contained in:
@@ -41,6 +41,7 @@ go_library(
|
||||
"//pkg/sentry/memmap",
|
||||
"//pkg/sentry/platform",
|
||||
"//pkg/sentry/platform/interrupt",
|
||||
"//pkg/sighandling",
|
||||
"//pkg/sync",
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
],
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
package ptrace
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/seccomp"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
@@ -26,6 +28,11 @@ func (*PTrace) SeccompInfo() platform.SeccompInfo {
|
||||
PlatformName: "ptrace",
|
||||
Filters: seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{
|
||||
unix.SYS_PTRACE: seccomp.MatchAll{},
|
||||
unix.SYS_RT_TGSIGQUEUEINFO: seccomp.PerArg{
|
||||
seccomp.EqualTo(os.Getpid()),
|
||||
seccomp.AnyValue{}, // tid
|
||||
seccomp.EqualTo(unix.SIGKILL),
|
||||
},
|
||||
unix.SYS_TGKILL: seccomp.MatchAll{},
|
||||
unix.SYS_WAIT4: seccomp.MatchAll{},
|
||||
}),
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/arch"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/sighandling"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
@@ -357,8 +358,7 @@ func (t *thread) unexpectedStubExit() {
|
||||
// these cases, we don't need to panic. There is no reasons to
|
||||
// think that something wrong in gVisor.
|
||||
log.Warningf("The ptrace stub process %v has been killed by SIGKILL.", t.tgid)
|
||||
pid := os.Getpid()
|
||||
unix.Tgkill(pid, pid, unix.Signal(unix.SIGKILL))
|
||||
sighandling.KillItself()
|
||||
}
|
||||
t.dumpAndPanic(fmt.Sprintf("wait failed: the process %d:%d exited: %x (err %v)", t.tgid, t.tid, msg, err))
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ go_library(
|
||||
"//pkg/sentry/platform/systrap/sysmsg",
|
||||
"//pkg/sentry/platform/systrap/usertrap",
|
||||
"//pkg/sentry/usage",
|
||||
"//pkg/sighandling",
|
||||
"//pkg/sync",
|
||||
"//pkg/syncevent",
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
package systrap
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/seccomp"
|
||||
@@ -93,7 +95,12 @@ func (systrapSeccomp) SyscallFilters(vars precompiledseccomp.Values) seccomp.Sys
|
||||
},
|
||||
},
|
||||
unix.SYS_TGKILL: seccomp.MatchAll{},
|
||||
unix.SYS_WAIT4: seccomp.MatchAll{},
|
||||
unix.SYS_RT_TGSIGQUEUEINFO: seccomp.PerArg{
|
||||
seccomp.EqualTo(os.Getpid()),
|
||||
seccomp.AnyValue{}, // tid
|
||||
seccomp.EqualTo(unix.SIGKILL),
|
||||
},
|
||||
unix.SYS_WAIT4: seccomp.MatchAll{},
|
||||
unix.SYS_IOCTL: seccomp.Or{
|
||||
seccomp.PerArg{
|
||||
seccomp.NonNegativeFD{},
|
||||
|
||||
@@ -16,7 +16,6 @@ package systrap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -36,6 +35,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform/systrap/sysmsg"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform/systrap/usertrap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/usage"
|
||||
"gvisor.dev/gvisor/pkg/sighandling"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -609,8 +609,7 @@ func (t *thread) unexpectedStubExit() {
|
||||
// these cases, we don't need to panic. There is no reasons to
|
||||
// think that something wrong in gVisor.
|
||||
log.Warningf("The ptrace stub process %v has been killed by SIGKILL.", t.tgid)
|
||||
pid := os.Getpid()
|
||||
unix.Tgkill(pid, pid, unix.Signal(unix.SIGKILL))
|
||||
sighandling.KillItself()
|
||||
}
|
||||
t.dumpAndPanic(fmt.Sprintf("wait failed: the process %d:%d exited: %x (err %v)", t.tgid, t.tid, msg, err))
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package sighandling
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -74,3 +75,29 @@ func ReplaceSignalHandler(sig unix.Signal, handler uintptr, previous *uintptr) e
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// KillItself sends SIGKILL to the current process, bypassing the init process
|
||||
// restriction.
|
||||
//
|
||||
// The standard `kill(getpid(), SIGKILL)` syscall doesn't work when the current
|
||||
// process is the init process within its PID namespace. This is a "known"
|
||||
// Linux feature.
|
||||
//
|
||||
// This function uses the rt_tgqueueinfo syscall to send a "kernel-generated"
|
||||
// SIGKILL.
|
||||
func KillItself() error {
|
||||
pid := os.Getpid()
|
||||
tid, _, _ := unix.RawSyscall(unix.SYS_GETTID, 0, 0, 0)
|
||||
info := linux.SignalInfo{Code: linux.SI_KERNEL}
|
||||
// The current thread can send a fake kernel siginfo to itself.
|
||||
if _, _, e := unix.RawSyscall6(
|
||||
unix.SYS_RT_TGSIGQUEUEINFO,
|
||||
uintptr(pid), uintptr(tid),
|
||||
uintptr(linux.SIGKILL),
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
0, 0,
|
||||
); e != 0 {
|
||||
return e
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user