From dc33d71f8cf11bede2b224f4be730916f7faac81 Mon Sep 17 00:00:00 2001 From: Adin Scannell Date: Tue, 26 Jun 2018 16:53:48 -0700 Subject: Change SIGCHLD to SIGKILL in ptrace stubs. If the child stubs are killed by any unmaskable signal (e.g. SIGKILL), then the parent process will similarly be killed, resulting in the death of all other stubs. The effect of this is that if the OOM killer selects and kills a stub, the effect is the same as though the OOM killer selected and killed the sentry. PiperOrigin-RevId: 202219984 Change-Id: I0b638ce7e59e0a0f4d5cde12a7d05242673049d7 --- pkg/sentry/platform/ptrace/subprocess_linux.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'pkg/sentry') diff --git a/pkg/sentry/platform/ptrace/subprocess_linux.go b/pkg/sentry/platform/ptrace/subprocess_linux.go index 227dd4882..b3f2ebb20 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux.go @@ -41,7 +41,15 @@ func createStub() (*thread, error) { // Among other things, beforeFork masks all signals. beforeFork() - pid, _, errno = syscall.RawSyscall6(syscall.SYS_CLONE, uintptr(syscall.SIGCHLD)|syscall.CLONE_FILES, 0, 0, 0, 0, 0) + + // When creating the new child process, we specify SIGKILL as the + // signal to deliver when the child exits. We never expect a subprocess + // to exit; they are pooled and reused. This is done to ensure that if + // a subprocess is OOM-killed, this process (and all other stubs, + // transitively) will be killed as well. It's simply not possible to + // safely handle a single stub getting killed: the exact state of + // execution is unknown and not recoverable. + pid, _, errno = syscall.RawSyscall6(syscall.SYS_CLONE, uintptr(syscall.SIGKILL)|syscall.CLONE_FILES, 0, 0, 0, 0, 0) if errno != 0 { afterFork() return nil, errno @@ -103,10 +111,12 @@ func (s *subprocess) createStub() (*thread, error) { // // Instead, we create the child untraced, which will do the PDEATHSIG // setup and then SIGSTOP itself for our attach below. + // + // See above re: SIGKILL. pid, err := t.syscallIgnoreInterrupt( ®s, syscall.SYS_CLONE, - arch.SyscallArgument{Value: uintptr(syscall.SIGCHLD | syscall.CLONE_FILES)}, + arch.SyscallArgument{Value: uintptr(syscall.SIGKILL | syscall.CLONE_FILES)}, arch.SyscallArgument{Value: 0}, arch.SyscallArgument{Value: 0}, arch.SyscallArgument{Value: 0}, @@ -127,7 +137,7 @@ func (s *subprocess) createStub() (*thread, error) { syscall.SYS_WAIT4, arch.SyscallArgument{Value: uintptr(pid)}, arch.SyscallArgument{Value: 0}, - arch.SyscallArgument{Value: syscall.WUNTRACED}, + arch.SyscallArgument{Value: syscall.WALL | syscall.WUNTRACED}, arch.SyscallArgument{Value: 0}, arch.SyscallArgument{Value: 0}, arch.SyscallArgument{Value: 0}) -- cgit v1.2.3