github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/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 "github.com/nicocha30/gvisor-ligolo/pkg/abi/linux" 23 "github.com/nicocha30/gvisor-ligolo/pkg/sentry/arch" 24 "github.com/nicocha30/gvisor-ligolo/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 43 // Set the parent death signal to SIGKILL. 44 _, err := t.syscallIgnoreInterrupt(&t.initRegs, unix.SYS_PRCTL, 45 arch.SyscallArgument{Value: linux.PR_SET_PDEATHSIG}, 46 arch.SyscallArgument{Value: uintptr(unix.SIGKILL)}, 47 arch.SyscallArgument{Value: 0}, 48 arch.SyscallArgument{Value: 0}, 49 arch.SyscallArgument{Value: 0}, 50 arch.SyscallArgument{Value: 0}, 51 ) 52 if err != nil { 53 panic(fmt.Sprintf("prctl: %v", err)) 54 } 55 56 // Set the sysmsg signal stack. 57 // 58 // sentryAddr is from the stub mapping which is mapped once and never 59 // moved, so it is safe to use unsafe.Pointer here. 60 alt := (*linux.SignalStack)(unsafe.Pointer(sentryAddr)) 61 *alt = linux.SignalStack{} 62 alt.Addr = uint64(guestAddr) 63 alt.Size = uint64(sysmsg.MsgOffsetFromSharedStack) 64 _, err = t.syscallIgnoreInterrupt(&t.initRegs, unix.SYS_SIGALTSTACK, 65 arch.SyscallArgument{Value: guestAddr}, 66 arch.SyscallArgument{Value: 0}, 67 arch.SyscallArgument{Value: 0}, 68 arch.SyscallArgument{Value: 0}, 69 arch.SyscallArgument{Value: 0}, 70 arch.SyscallArgument{Value: 0}, 71 ) 72 if err != nil { 73 panic(fmt.Sprintf("sigaltstack: %v", err)) 74 } 75 } 76 77 // sysmsgSigactions installs signal handles for signals which can be triggered 78 // by stubProcess and have to be handled by Sentry. 79 // 80 // It is called in a child process after fork(), so the race instrumentation 81 // has to be disabled. 82 // 83 //go:nosplit 84 //go:norace 85 func sysmsgSigactions(stubSysmsgStart uintptr) unix.Errno { 86 act := linux.SigAction{ 87 Handler: uint64(stubSysmsgStart) + uint64(sysmsg.Sighandler_blob_offset____export_sighandler), 88 Flags: linux.SA_ONSTACK | linux.SA_RESTORER | linux.SA_SIGINFO, 89 Restorer: uint64(stubSysmsgStart) + uint64(sysmsg.Sighandler_blob_offset____export_restore_rt), 90 Mask: 1<<(linux.SIGCHLD-1) | 1<<(linux.SIGSYS-1), 91 } 92 93 for _, s := range []unix.Signal{ 94 unix.SIGSYS, 95 unix.SIGBUS, 96 unix.SIGFPE, 97 unix.SIGILL, 98 unix.SIGCHLD, 99 unix.SIGTRAP, 100 unix.SIGSEGV, 101 } { 102 _, _, errno := unix.RawSyscall6(unix.SYS_RT_SIGACTION, uintptr(s), uintptr(unsafe.Pointer(&act)), 0, 8, 0, 0) 103 if errno != 0 { 104 return errno 105 } 106 } 107 108 return 0 109 }