Commit fbbef764 authored by Paul Mackerras's avatar Paul Mackerras Committed by Linus Torvalds

[PATCH] PPC64: Fix possible race in syscall restart

This is the PPC64 counterpart of the fix for the potential race in the
syscall restart code that has gone into other architectures.  It resets
current_thread_info()->restart_block.fn to do_no_syscall_restart in
the sigreturn code.
parent a494abf0
...@@ -220,6 +220,9 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -220,6 +220,9 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
sigset_t set; sigset_t set;
stack_t st; stack_t st;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
if (verify_area(VERIFY_READ, uc, sizeof(*uc))) if (verify_area(VERIFY_READ, uc, sizeof(*uc)))
goto badframe; goto badframe;
...@@ -354,8 +357,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) ...@@ -354,8 +357,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
{ {
switch ((int)regs->result) { switch ((int)regs->result) {
case -ERESTART_RESTARTBLOCK: case -ERESTART_RESTARTBLOCK:
current_thread_info()->restart_block.fn = do_no_restart_syscall;
/* fallthrough */
case -ERESTARTNOHAND: case -ERESTARTNOHAND:
/* ERESTARTNOHAND means that the syscall should only be /* ERESTARTNOHAND means that the syscall should only be
* restarted if there was no handler for the signal, and since * restarted if there was no handler for the signal, and since
......
...@@ -300,6 +300,9 @@ static void setup_frame32(struct pt_regs *regs, struct sigregs32 *frame, ...@@ -300,6 +300,9 @@ static void setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
struct sigcontext32 *sc = (struct sigcontext32 *)(u64)newsp; struct sigcontext32 *sc = (struct sigcontext32 *)(u64)newsp;
int i; int i;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
if (verify_area(VERIFY_WRITE, frame, sizeof(*frame))) if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
goto badframe; goto badframe;
if (regs->msr & MSR_FP) if (regs->msr & MSR_FP)
...@@ -420,6 +423,9 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -420,6 +423,9 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
int i; int i;
mm_segment_t old_fs; mm_segment_t old_fs;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
/* Adjust the inputted reg1 to point to the first rt signal frame */ /* Adjust the inputted reg1 to point to the first rt signal frame */
rt_sf = (struct rt_sigframe_32 *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32); rt_sf = (struct rt_sigframe_32 *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
/* Copy the information from the user stack */ /* Copy the information from the user stack */
......
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