github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/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  	"github.com/nicocha30/gvisor-ligolo/pkg/abi/linux"
    21  	"github.com/nicocha30/gvisor-ligolo/pkg/log"
    22  	"github.com/nicocha30/gvisor-ligolo/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  }