gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/platform/systrap/sysmsg_thread_unsafe.go (about) 1 // Copyright 2020 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 package systrap 16 17 import ( 18 "fmt" 19 "unsafe" 20 21 "golang.org/x/sys/unix" 22 "gvisor.dev/gvisor/pkg/abi/linux" 23 "gvisor.dev/gvisor/pkg/sentry/arch" 24 "gvisor.dev/gvisor/pkg/sentry/platform/systrap/sysmsg" 25 ) 26 27 func (p *sysmsgThread) unmapStackFromSentry() { 28 _, _, errno := unix.RawSyscall(unix.SYS_MUNMAP, sysmsg.MsgToStackAddr(uintptr(unsafe.Pointer(p.msg))), sysmsg.PerThreadSharedStackSize, 0) 29 if errno != 0 { 30 panic("failed to unmap: " + errno.Error()) 31 } 32 } 33 34 func (p *sysmsgThread) setMsg(addr uintptr) { 35 // add is always from the stub mapping which is mapped once and never 36 // moved, so it is safe to use unsafe.Pointer here. 37 p.msg = (*sysmsg.Msg)(unsafe.Pointer(addr)) 38 } 39 40 func (p *sysmsgThread) init(sentryAddr, guestAddr uintptr) { 41 t := p.thread 42 // Set the sysmsg signal stack. 43 // 44 // sentryAddr is from the stub mapping which is mapped once and never 45 // moved, so it is safe to use unsafe.Pointer here. 46 alt := (*linux.SignalStack)(unsafe.Pointer(sentryAddr)) 47 *alt = linux.SignalStack{} 48 alt.Addr = uint64(guestAddr) 49 alt.Size = uint64(sysmsg.MsgOffsetFromSharedStack) 50 _, err := t.syscallIgnoreInterrupt(&t.initRegs, unix.SYS_SIGALTSTACK, 51 arch.SyscallArgument{Value: guestAddr}, 52 arch.SyscallArgument{Value: 0}, 53 arch.SyscallArgument{Value: 0}, 54 arch.SyscallArgument{Value: 0}, 55 arch.SyscallArgument{Value: 0}, 56 arch.SyscallArgument{Value: 0}, 57 ) 58 if err != nil { 59 panic(fmt.Sprintf("sigaltstack: %v", err)) 60 } 61 } 62 63 // sysmsgSigactions installs signal handles for signals which can be triggered 64 // by stubProcess and have to be handled by Sentry. 65 // 66 // It is called in a child process after fork(), so the race instrumentation 67 // has to be disabled. 68 // 69 //go:nosplit 70 //go:norace 71 func sysmsgSigactions(stubSysmsgStart uintptr) unix.Errno { 72 act := linux.SigAction{ 73 Handler: uint64(stubSysmsgStart) + uint64(sysmsg.Sighandler_blob_offset____export_sighandler), 74 Flags: linux.SA_ONSTACK | linux.SA_RESTORER | linux.SA_SIGINFO, 75 Restorer: uint64(stubSysmsgStart) + uint64(sysmsg.Sighandler_blob_offset____export_restore_rt), 76 Mask: 1<<(linux.SIGCHLD-1) | 1<<(linux.SIGSYS-1), 77 } 78 79 for _, s := range []unix.Signal{ 80 unix.SIGSYS, 81 unix.SIGBUS, 82 unix.SIGFPE, 83 unix.SIGILL, 84 unix.SIGCHLD, 85 unix.SIGTRAP, 86 unix.SIGSEGV, 87 } { 88 _, _, errno := unix.RawSyscall6(unix.SYS_RT_SIGACTION, uintptr(s), uintptr(unsafe.Pointer(&act)), 0, 8, 0, 0) 89 if errno != 0 { 90 return errno 91 } 92 } 93 94 return 0 95 }