summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/arch/signal_amd64.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/arch/signal_amd64.go')
-rw-r--r--pkg/sentry/arch/signal_amd64.go16
1 files changed, 12 insertions, 4 deletions
diff --git a/pkg/sentry/arch/signal_amd64.go b/pkg/sentry/arch/signal_amd64.go
index 4040b530f..c1d743f38 100644
--- a/pkg/sentry/arch/signal_amd64.go
+++ b/pkg/sentry/arch/signal_amd64.go
@@ -377,6 +377,14 @@ func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt
sp = frameBottom + usermem.Addr(frameSize)
st.Bottom = sp
+ // Prior to proceeding, figure out if the frame will exhaust the range
+ // for the signal stack. This is not allowed, and should immediately
+ // force signal delivery (reverting to the default handler).
+ if act.IsOnStack() && alt.IsEnabled() && !alt.Contains(frameBottom) {
+ return syscall.EFAULT
+ }
+
+ // Adjust the code.
info.FixSignalCodeForUser()
// Set up the stack frame.
@@ -422,15 +430,15 @@ func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt
// SignalRestore implements Context.SignalRestore. (Compare to Linux's
// arch/x86/kernel/signal.c:sys_rt_sigreturn().)
-func (c *context64) SignalRestore(st *Stack, rt bool) (linux.SignalSet, error) {
+func (c *context64) SignalRestore(st *Stack, rt bool) (linux.SignalSet, SignalStack, error) {
// Copy out the stack frame.
var uc UContext64
if _, err := st.Pop(&uc); err != nil {
- return 0, err
+ return 0, SignalStack{}, err
}
var info SignalInfo
if _, err := st.Pop(&info); err != nil {
- return 0, err
+ return 0, SignalStack{}, err
}
// Restore registers.
@@ -472,5 +480,5 @@ func (c *context64) SignalRestore(st *Stack, rt bool) (linux.SignalSet, error) {
log.Infof("sigreturn unable to restore application fpstate")
}
- return uc.Sigset, nil
+ return uc.Sigset, uc.Stack, nil
}