Skip to content

Commit

Permalink
linux-user/sparc: Minor corrections to do_sigreturn
Browse files Browse the repository at this point in the history
Check that the input sp is 16 byte aligned, not 4.
Do that before the lock_user_struct check.

Validate the saved sp is 8 byte aligned.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20210426025334.1168495-22-richard.henderson@linaro.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
  • Loading branch information
rth7680 authored and vivier committed May 15, 2021
1 parent 757d260 commit 1176e57
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions linux-user/sparc/signal.c
Expand Up @@ -254,26 +254,29 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
long do_sigreturn(CPUSPARCState *env)
{
abi_ulong sf_addr;
struct target_signal_frame *sf;
struct target_signal_frame *sf = NULL;
abi_ulong pc, npc, ptr;
target_sigset_t set;
sigset_t host_set;
int i;

sf_addr = env->regwptr[WREG_SP];
trace_user_do_sigreturn(env, sf_addr);
if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) {
goto segv_and_exit;
}

/* 1. Make sure we are not getting garbage from the user */
if ((sf_addr & 15) || !lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) {
goto segv_and_exit;
}

if (sf_addr & 3)
/* Make sure stack pointer is aligned. */
__get_user(ptr, &sf->regs.u_regs[14]);
if (ptr & 7) {
goto segv_and_exit;
}

__get_user(pc, &sf->regs.pc);
/* Make sure instruction pointers are aligned. */
__get_user(pc, &sf->regs.pc);
__get_user(npc, &sf->regs.npc);

if ((pc | npc) & 3) {
goto segv_and_exit;
}
Expand Down Expand Up @@ -309,7 +312,7 @@ long do_sigreturn(CPUSPARCState *env)
unlock_user_struct(sf, sf_addr, 0);
return -TARGET_QEMU_ESIGRETURN;

segv_and_exit:
segv_and_exit:
unlock_user_struct(sf, sf_addr, 0);
force_sig(TARGET_SIGSEGV);
return -TARGET_QEMU_ESIGRETURN;
Expand Down

0 comments on commit 1176e57

Please sign in to comment.