github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/sentry/kernel/signal_handlers.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 "github.com/nicocha30/gvisor-ligolo/pkg/abi/linux" 19 ) 20 21 // SignalHandlers holds information about signal actions. 22 // 23 // +stateify savable 24 type SignalHandlers struct { 25 // mu protects actions, as well as the signal state of all tasks and thread 26 // groups using this SignalHandlers object. (See comment on 27 // ThreadGroup.signalHandlers.) 28 mu signalHandlersMutex `state:"nosave"` 29 30 // actions is the action to be taken upon receiving each signal. 31 actions map[linux.Signal]linux.SigAction 32 } 33 34 // NewSignalHandlers returns a new SignalHandlers specifying all default 35 // actions. 36 func NewSignalHandlers() *SignalHandlers { 37 return &SignalHandlers{ 38 actions: make(map[linux.Signal]linux.SigAction), 39 } 40 } 41 42 // Fork returns a copy of sh for a new thread group. 43 func (sh *SignalHandlers) Fork() *SignalHandlers { 44 sh2 := NewSignalHandlers() 45 sh.mu.Lock() 46 defer sh.mu.Unlock() 47 for sig, act := range sh.actions { 48 sh2.actions[sig] = act 49 } 50 return sh2 51 } 52 53 // CopyForExec returns a copy of sh for a thread group that is undergoing an 54 // execve. (See comments in Task.finishExec.) 55 func (sh *SignalHandlers) CopyForExec() *SignalHandlers { 56 sh2 := NewSignalHandlers() 57 sh.mu.Lock() 58 defer sh.mu.Unlock() 59 for sig, act := range sh.actions { 60 if act.Handler == linux.SIG_IGN { 61 sh2.actions[sig] = linux.SigAction{ 62 Handler: linux.SIG_IGN, 63 } 64 } 65 } 66 return sh2 67 } 68 69 // IsIgnored returns true if the signal is ignored. 70 func (sh *SignalHandlers) IsIgnored(sig linux.Signal) bool { 71 sh.mu.Lock() 72 defer sh.mu.Unlock() 73 sa, ok := sh.actions[sig] 74 return ok && sa.Handler == linux.SIG_IGN 75 } 76 77 // dequeueActionLocked returns the SignalAct that should be used to handle sig. 78 // 79 // Preconditions: sh.mu must be locked. 80 func (sh *SignalHandlers) dequeueAction(sig linux.Signal) linux.SigAction { 81 act := sh.actions[sig] 82 if act.Flags&linux.SA_RESETHAND != 0 { 83 delete(sh.actions, sig) 84 } 85 return act 86 }