From fbbef764ed4c4417924b803d86467835de2a448b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 18 Nov 2003 00:12:15 -0800 Subject: [PATCH] [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. --- arch/ppc64/kernel/signal.c | 5 +++-- arch/ppc64/kernel/signal32.c | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c index 3147d036abe78..f6b0cba9cd57e 100644 --- a/arch/ppc64/kernel/signal.c +++ b/arch/ppc64/kernel/signal.c @@ -220,6 +220,9 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, sigset_t set; 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))) goto badframe; @@ -354,8 +357,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) { switch ((int)regs->result) { case -ERESTART_RESTARTBLOCK: - current_thread_info()->restart_block.fn = do_no_restart_syscall; - /* fallthrough */ case -ERESTARTNOHAND: /* ERESTARTNOHAND means that the syscall should only be * restarted if there was no handler for the signal, and since diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c index 756cc83a810ed..bd371a56df730 100644 --- a/arch/ppc64/kernel/signal32.c +++ b/arch/ppc64/kernel/signal32.c @@ -300,6 +300,9 @@ static void setup_frame32(struct pt_regs *regs, struct sigregs32 *frame, struct sigcontext32 *sc = (struct sigcontext32 *)(u64)newsp; 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))) goto badframe; if (regs->msr & MSR_FP) @@ -420,6 +423,9 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, int i; 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 */ rt_sf = (struct rt_sigframe_32 *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32); /* Copy the information from the user stack */ -- 2.53.0