gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/platform/systrap/syscall_thread_amd64.go (about)

     1  // Copyright 2021 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  //go:build amd64
    16  // +build amd64
    17  
    18  package systrap
    19  
    20  import (
    21  	"fmt"
    22  	"runtime"
    23  
    24  	"golang.org/x/sys/unix"
    25  	"gvisor.dev/gvisor/pkg/sentry/arch"
    26  )
    27  
    28  func (t *syscallThread) detach() {
    29  	p := t.thread
    30  
    31  	// The syscall thread can't handle any signals and doesn't expect to
    32  	// receive anything.
    33  	t.maskAllSignalsAttached()
    34  
    35  	regs := p.initRegs
    36  	regs.Rsp = 0
    37  	regs.R12 = uint64(t.stubAddr)
    38  	regs.R13 = uint64(t.sentryMessage.state + 1)
    39  	if t.seccompNotify != nil {
    40  		regs.Rbx = _RUN_SECCOMP_LOOP
    41  	} else {
    42  		regs.Rbx = _RUN_SYSCALL_LOOP
    43  	}
    44  	// Skip the syscall instruction.
    45  	regs.Rip += arch.SyscallWidth
    46  	if err := p.setRegs(&regs); err != nil {
    47  		panic(fmt.Sprintf("ptrace set regs failed: %v", err))
    48  	}
    49  	p.detach()
    50  	if _, _, e := unix.RawSyscall(unix.SYS_TGKILL, uintptr(p.tgid), uintptr(p.tid), uintptr(unix.SIGCONT)); e != 0 {
    51  		panic(fmt.Sprintf("tkill failed: %v", e))
    52  	}
    53  	runtime.UnlockOSThread()
    54  
    55  	if t.seccompNotify != nil {
    56  		if err := t.waitForSeccompNotify(); err != nil {
    57  			panic(fmt.Sprintf("%s", err))
    58  		}
    59  	}
    60  }