gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/kernel/signal.go (about) 1 // Copyright 2018 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 kernel 16 17 import ( 18 "fmt" 19 20 "gvisor.dev/gvisor/pkg/abi/linux" 21 "gvisor.dev/gvisor/pkg/log" 22 "gvisor.dev/gvisor/pkg/sentry/platform" 23 ) 24 25 // SignalPanic is used to panic the running threads. It is a signal which 26 // cannot be used by the application: it must be caught and ignored by the 27 // runtime (in order to catch possible races). 28 const SignalPanic = linux.SIGUSR2 29 30 // sendExternalSignal is called when an asynchronous signal is sent to the 31 // sentry ("in sentry context"). On some platforms, it may also be called when 32 // an asynchronous signal is sent to sandboxed application threads ("in 33 // application context"). 34 // 35 // context is used only for debugging to differentiate these cases. 36 // 37 // Preconditions: Kernel must have an init process. 38 func (k *Kernel) sendExternalSignal(info *linux.SignalInfo, context string) { 39 switch linux.Signal(info.Signo) { 40 case linux.SIGURG: 41 // Sent by the Go 1.14+ runtime for asynchronous goroutine preemption. 42 43 case platform.SignalInterrupt: 44 // Assume that a call to platform.Context.Interrupt() misfired. 45 46 case SignalPanic: 47 // SignalPanic is also specially handled in sentry setup to ensure that 48 // it causes a panic even after tasks exit, but SignalPanic may also 49 // be sent here if it is received while in app context. 50 panic("Signal-induced panic") 51 52 default: 53 log.Infof("Received external signal %d in %s context", info.Signo, context) 54 if k.globalInit == nil { 55 panic(fmt.Sprintf("Received external signal %d before init created", info.Signo)) 56 } 57 k.globalInit.SendSignal(info) 58 } 59 } 60 61 // SignalInfoPriv returns a SignalInfo equivalent to Linux's SEND_SIG_PRIV. 62 func SignalInfoPriv(sig linux.Signal) *linux.SignalInfo { 63 return &linux.SignalInfo{ 64 Signo: int32(sig), 65 Code: linux.SI_KERNEL, 66 } 67 } 68 69 // SignalInfoNoInfo returns a SignalInfo equivalent to Linux's SEND_SIG_NOINFO. 70 func SignalInfoNoInfo(sig linux.Signal, sender, receiver *Task) *linux.SignalInfo { 71 info := &linux.SignalInfo{ 72 Signo: int32(sig), 73 Code: linux.SI_USER, 74 } 75 info.SetPID(int32(receiver.tg.pidns.IDOfThreadGroup(sender.tg))) 76 info.SetUID(int32(sender.Credentials().RealKUID.In(receiver.UserNamespace()).OrOverflow())) 77 return info 78 }