Fix the arm sys_sigreturn(): its argument is a struct ucontext, not a

struct sigframe containing the struct ucontext.

The signal trampoline return code on the other hand DOES have just a
struct sigframe on the stack to work with, so have it get a pointer to
the ucontext out of there to pass along to sys_sigreturn.

In other words, make everything work right whether sys_sigreturn is
invoked from the trampoline or from userland code calling sigreturn(2).

Submitted by:	Takashi Komatsu <komatsu.taka@jp.panasonic.com>
Reviewed by:	cognet
This commit is contained in:
ian 2014-03-07 20:32:45 +00:00
parent af733395cb
commit 11fd7cf299
3 changed files with 8 additions and 7 deletions

View File

@ -109,6 +109,8 @@ ASSYM(TF_PC, offsetof(struct trapframe, tf_pc));
ASSYM(P_PID, offsetof(struct proc, p_pid)); ASSYM(P_PID, offsetof(struct proc, p_pid));
ASSYM(P_FLAG, offsetof(struct proc, p_flag)); ASSYM(P_FLAG, offsetof(struct proc, p_flag));
ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
#ifdef ARM_TP_ADDRESS #ifdef ARM_TP_ADDRESS
ASSYM(ARM_TP_ADDRESS, ARM_TP_ADDRESS); ASSYM(ARM_TP_ADDRESS, ARM_TP_ADDRESS);
ASSYM(ARM_RAS_START, ARM_RAS_START); ASSYM(ARM_RAS_START, ARM_RAS_START);

View File

@ -557,6 +557,7 @@ END(abort)
ENTRY_NP(sigcode) ENTRY_NP(sigcode)
mov r0, sp mov r0, sp
add r0, r0, #SIGF_UC
/* /*
* Call the sigreturn system call. * Call the sigreturn system call.

View File

@ -742,28 +742,26 @@ sys_sigreturn(td, uap)
const struct __ucontext *sigcntxp; const struct __ucontext *sigcntxp;
} */ *uap; } */ *uap;
{ {
struct sigframe sf; ucontext_t uc;
struct trapframe *tf;
int spsr; int spsr;
if (uap == NULL) if (uap == NULL)
return (EFAULT); return (EFAULT);
if (copyin(uap->sigcntxp, &sf, sizeof(sf))) if (copyin(uap->sigcntxp, &uc, sizeof(uc)))
return (EFAULT); return (EFAULT);
/* /*
* Make sure the processor mode has not been tampered with and * Make sure the processor mode has not been tampered with and
* interrupts have not been disabled. * interrupts have not been disabled.
*/ */
spsr = sf.sf_uc.uc_mcontext.__gregs[_REG_CPSR]; spsr = uc.uc_mcontext.__gregs[_REG_CPSR];
if ((spsr & PSR_MODE) != PSR_USR32_MODE || if ((spsr & PSR_MODE) != PSR_USR32_MODE ||
(spsr & (I32_bit | F32_bit)) != 0) (spsr & (I32_bit | F32_bit)) != 0)
return (EINVAL); return (EINVAL);
/* Restore register context. */ /* Restore register context. */
tf = td->td_frame; set_mcontext(td, &uc.uc_mcontext);
set_mcontext(td, &sf.sf_uc.uc_mcontext);
/* Restore signal mask. */ /* Restore signal mask. */
kern_sigprocmask(td, SIG_SETMASK, &sf.sf_uc.uc_sigmask, NULL, 0); kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
return (EJUSTRETURN); return (EJUSTRETURN);
} }