提交 10469350 编写于 作者: C Christian Ruppert 提交者: Vineet Gupta

ARC: Fix signal frame management for SA_SIGINFO

Previously, when a signal was registered with SA_SIGINFO, parameters 2
and 3 of the signal handler were written to registers r1 and r2 before
the register set was saved. This led to corruption of these two
registers after returning from the signal handler (the wrong values were
restored).
With this patch, registers are now saved before any parameters are
passed, thus maintaining the processor state from before signal entry.
Signed-off-by: NChristian Ruppert <christian.ruppert@abilis.com>
Signed-off-by: NVineet Gupta <vgupta@synopsys.com>
上级 55c2e262
...@@ -101,7 +101,6 @@ SYSCALL_DEFINE0(rt_sigreturn) ...@@ -101,7 +101,6 @@ SYSCALL_DEFINE0(rt_sigreturn)
{ {
struct rt_sigframe __user *sf; struct rt_sigframe __user *sf;
unsigned int magic; unsigned int magic;
int err;
struct pt_regs *regs = current_pt_regs(); struct pt_regs *regs = current_pt_regs();
/* Always make any pending restarted system calls return -EINTR */ /* Always make any pending restarted system calls return -EINTR */
...@@ -119,15 +118,16 @@ SYSCALL_DEFINE0(rt_sigreturn) ...@@ -119,15 +118,16 @@ SYSCALL_DEFINE0(rt_sigreturn)
if (!access_ok(VERIFY_READ, sf, sizeof(*sf))) if (!access_ok(VERIFY_READ, sf, sizeof(*sf)))
goto badframe; goto badframe;
err = restore_usr_regs(regs, sf); if (__get_user(magic, &sf->sigret_magic))
err |= __get_user(magic, &sf->sigret_magic);
if (err)
goto badframe; goto badframe;
if (unlikely(is_do_ss_needed(magic))) if (unlikely(is_do_ss_needed(magic)))
if (restore_altstack(&sf->uc.uc_stack)) if (restore_altstack(&sf->uc.uc_stack))
goto badframe; goto badframe;
if (restore_usr_regs(regs, sf))
goto badframe;
/* Don't restart from sigreturn */ /* Don't restart from sigreturn */
syscall_wont_restart(regs); syscall_wont_restart(regs);
...@@ -190,6 +190,15 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info, ...@@ -190,6 +190,15 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
if (!sf) if (!sf)
return 1; return 1;
/*
* w/o SA_SIGINFO, struct ucontext is partially populated (only
* uc_mcontext/uc_sigmask) for kernel's normal user state preservation
* during signal handler execution. This works for SA_SIGINFO as well
* although the semantics are now overloaded (the same reg state can be
* inspected by userland: but are they allowed to fiddle with it ?
*/
err |= stash_usr_regs(sf, regs, set);
/* /*
* SA_SIGINFO requires 3 args to signal handler: * SA_SIGINFO requires 3 args to signal handler:
* #1: sig-no (common to any handler) * #1: sig-no (common to any handler)
...@@ -213,14 +222,6 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info, ...@@ -213,14 +222,6 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
magic = MAGIC_SIGALTSTK; magic = MAGIC_SIGALTSTK;
} }
/*
* w/o SA_SIGINFO, struct ucontext is partially populated (only
* uc_mcontext/uc_sigmask) for kernel's normal user state preservation
* during signal handler execution. This works for SA_SIGINFO as well
* although the semantics are now overloaded (the same reg state can be
* inspected by userland: but are they allowed to fiddle with it ?
*/
err |= stash_usr_regs(sf, regs, set);
err |= __put_user(magic, &sf->sigret_magic); err |= __put_user(magic, &sf->sigret_magic);
if (err) if (err)
return err; return err;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册