Commit c2785259 authored by David S. Miller's avatar David S. Miller

sparc: Prevent no-handler signal syscall restart recursion.

Explicitly clear the "in-syscall" bit when we have no signal
handler and back up the program counters to back up the system
call.
Reported-by: default avatarAl Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 392c2180
...@@ -616,7 +616,7 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, ...@@ -616,7 +616,7 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
flush_signal_insns(address); flush_signal_insns(address);
} }
return; return 0;
sigill: sigill:
do_exit(SIGILL); do_exit(SIGILL);
...@@ -840,12 +840,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -840,12 +840,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
regs->u_regs[UREG_I0] = orig_i0; regs->u_regs[UREG_I0] = orig_i0;
regs->tpc -= 4; regs->tpc -= 4;
regs->tnpc -= 4; regs->tnpc -= 4;
pt_regs_clear_syscall(regs);
} }
if (restart_syscall && if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->tpc -= 4; regs->tpc -= 4;
regs->tnpc -= 4; regs->tnpc -= 4;
pt_regs_clear_syscall(regs);
} }
/* If there's no signal to deliver, we just put the saved sigmask /* If there's no signal to deliver, we just put the saved sigmask
......
...@@ -580,12 +580,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) ...@@ -580,12 +580,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
regs->u_regs[UREG_I0] = orig_i0; regs->u_regs[UREG_I0] = orig_i0;
regs->pc -= 4; regs->pc -= 4;
regs->npc -= 4; regs->npc -= 4;
pt_regs_clear_syscall(regs);
} }
if (restart_syscall && if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->pc -= 4; regs->pc -= 4;
regs->npc -= 4; regs->npc -= 4;
pt_regs_clear_syscall(regs);
} }
/* if there's no signal to deliver, we just put the saved sigmask /* if there's no signal to deliver, we just put the saved sigmask
......
...@@ -600,12 +600,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) ...@@ -600,12 +600,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
regs->u_regs[UREG_I0] = orig_i0; regs->u_regs[UREG_I0] = orig_i0;
regs->tpc -= 4; regs->tpc -= 4;
regs->tnpc -= 4; regs->tnpc -= 4;
pt_regs_clear_syscall(regs);
} }
if (restart_syscall && if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->tpc -= 4; regs->tpc -= 4;
regs->tnpc -= 4; regs->tnpc -= 4;
pt_regs_clear_syscall(regs);
} }
/* If there's no signal to deliver, we just put the saved sigmask /* If there's no signal to deliver, we just put the saved sigmask
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment