]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] PPC64: Fix possible race in syscall restart
authorPaul Mackerras <paulus@samba.org>
Tue, 18 Nov 2003 08:12:15 +0000 (00:12 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Tue, 18 Nov 2003 08:12:15 +0000 (00:12 -0800)
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
arch/ppc64/kernel/signal32.c

index 3147d036abe78aeac4774cfe2f8bb0f377c0f7a5..f6b0cba9cd57e7556fd9c57f4914bd9123446afa 100644 (file)
@@ -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
index 756cc83a810ed5753be8653b6eb80110b35701d3..bd371a56df7300651f07c65c0a5bbed7c4cac33a 100644 (file)
@@ -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  */