mirror of https://gitee.com/openkylin/linux.git
ARC signal handling related fixes uncovered during recent testing of NPTL tools
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJVFTw+AAoJEGnX8d3iisJeojUP/12ANSkctP29kOjZFkZrav6v M9qaSR0NqtuxqQ7o8SY4FeA61/vKvy0Sfg5aqfLq1b4YU7FJginyOxZv+d3NPNto HCS4XVJwFiEmqYx6EgIrCnYmxNQsRTseJEI24/ImHmzvnjufx/JQ9wr0wQVcw/S3 ewxIyf0uyyVJ2UAOMjn2F3ukJYIpteItyT/59ndWluB/+JTHhhJUsIYowP2irU29 EsvEiExNv5d+n35gtxY7GdKEsX5bQc8bTT2UiladcWYIWdb9OoV4+L8MgFh7JHii vV71D4kdH5bhJsD1D98nm9jFpP6GfPWCY2BMTIhWIYmg+2Zl+cfiaYgIIuBYNG+x +ahrqB5Nbm+Ux4R7KnIYlXMgDiWMPetkAptUmbod293M/pXPyyQtFhiaB2X9l6Bl 48IUvWYjSp5p8mfhwBXcMItTazrv46HqarHfl3NG0sljRc9BwdPqlumhB1xxsQXg iauvvD6s6GHRIGapYlINRww9mCaNu5bTcY9cD6AHEc++6Ov/ZYpWnnipmUINNCmL 4yLd+pUQ6QoPuvCHbpzdEvb/eb/LDSbo17nB3aPNn/pPGzICgAXnhY4ET6nzZ3LM Dc/8FfrYmalYHmjeoWC8CPR/XmrmI7xCkNlF/kre+vCWRLs8Zewl/btxyU48+hho 81HBp3a0QCzCOcFKvzam =zVXd -----END PGP SIGNATURE----- Merge tag 'arc-4.0-fixes-part-2' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc Pull ARC fixes from Vineet Gupta: "We found some issues with signal handling taking down the system. I know its late, but these are important and all marked for stable. ARC signal handling related fixes uncovered during recent testing of NPTL tools" * tag 'arc-4.0-fixes-part-2' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: ARC: signal handling robustify ARC: SA_SIGINFO ucontext regs off-by-one
This commit is contained in:
commit
af0c11ca80
|
@ -67,7 +67,7 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs,
|
||||||
sigset_t *set)
|
sigset_t *set)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
err = __copy_to_user(&(sf->uc.uc_mcontext.regs), regs,
|
err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), regs,
|
||||||
sizeof(sf->uc.uc_mcontext.regs.scratch));
|
sizeof(sf->uc.uc_mcontext.regs.scratch));
|
||||||
err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t));
|
err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t));
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
|
||||||
if (!err)
|
if (!err)
|
||||||
set_current_blocked(&set);
|
set_current_blocked(&set);
|
||||||
|
|
||||||
err |= __copy_from_user(regs, &(sf->uc.uc_mcontext.regs),
|
err |= __copy_from_user(regs, &(sf->uc.uc_mcontext.regs.scratch),
|
||||||
sizeof(sf->uc.uc_mcontext.regs.scratch));
|
sizeof(sf->uc.uc_mcontext.regs.scratch));
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -131,6 +131,15 @@ SYSCALL_DEFINE0(rt_sigreturn)
|
||||||
/* Don't restart from sigreturn */
|
/* Don't restart from sigreturn */
|
||||||
syscall_wont_restart(regs);
|
syscall_wont_restart(regs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure that sigreturn always returns to user mode (in case the
|
||||||
|
* regs saved on user stack got fudged between save and sigreturn)
|
||||||
|
* Otherwise it is easy to panic the kernel with a custom
|
||||||
|
* signal handler and/or restorer which clobberes the status32/ret
|
||||||
|
* to return to a bogus location in kernel mode.
|
||||||
|
*/
|
||||||
|
regs->status32 |= STATUS_U_MASK;
|
||||||
|
|
||||||
return regs->r0;
|
return regs->r0;
|
||||||
|
|
||||||
badframe:
|
badframe:
|
||||||
|
@ -229,8 +238,11 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handler returns using sigreturn stub provided already by userpsace
|
* handler returns using sigreturn stub provided already by userpsace
|
||||||
|
* If not, nuke the process right away
|
||||||
*/
|
*/
|
||||||
BUG_ON(!(ksig->ka.sa.sa_flags & SA_RESTORER));
|
if(!(ksig->ka.sa.sa_flags & SA_RESTORER))
|
||||||
|
return 1;
|
||||||
|
|
||||||
regs->blink = (unsigned long)ksig->ka.sa.sa_restorer;
|
regs->blink = (unsigned long)ksig->ka.sa.sa_restorer;
|
||||||
|
|
||||||
/* User Stack for signal handler will be above the frame just carved */
|
/* User Stack for signal handler will be above the frame just carved */
|
||||||
|
@ -296,12 +308,12 @@ static void
|
||||||
handle_signal(struct ksignal *ksig, struct pt_regs *regs)
|
handle_signal(struct ksignal *ksig, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
sigset_t *oldset = sigmask_to_save();
|
sigset_t *oldset = sigmask_to_save();
|
||||||
int ret;
|
int failed;
|
||||||
|
|
||||||
/* Set up the stack frame */
|
/* Set up the stack frame */
|
||||||
ret = setup_rt_frame(ksig, oldset, regs);
|
failed = setup_rt_frame(ksig, oldset, regs);
|
||||||
|
|
||||||
signal_setup_done(ret, ksig, 0);
|
signal_setup_done(failed, ksig, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_signal(struct pt_regs *regs)
|
void do_signal(struct pt_regs *regs)
|
||||||
|
|
Loading…
Reference in New Issue