diff options
author | Adin Scannell <ascannell@google.com> | 2018-06-08 15:00:29 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-06-08 15:01:21 -0700 |
commit | 6728f09910bd9f7633f277fafe6945cfaa2abf42 (patch) | |
tree | 3f753ec51b176934e8eef6d56522d6dddb3c10f7 /pkg/sentry/arch/signal_amd64.go | |
parent | de8dba205f66a07c793619a3896f2376b41a4b55 (diff) |
Fix sigaltstack semantics.
Walking off the bottom of the sigaltstack, for example with recursive faults,
results in forced signal delivery, not resetting the stack or pushing signal
stack to whatever happens to lie below the signal stack.
PiperOrigin-RevId: 199856085
Change-Id: I0004d2523f0df35d18714de2685b3eaa147837e0
Diffstat (limited to 'pkg/sentry/arch/signal_amd64.go')
-rw-r--r-- | pkg/sentry/arch/signal_amd64.go | 16 |
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 } |