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