]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] x86_64: fix syscall/signal restart bug
authorAndi Kleen <ak@suse.de>
Mon, 20 Dec 2004 08:06:46 +0000 (00:06 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 20 Dec 2004 08:06:46 +0000 (00:06 -0800)
Fix a pretty bad bug that caused sometimes signals on x86-64
to be restarted like system calls. This corrupted the RIP and
in general caused undesirable effects.

The problem happens because orig_rax is unsigned on x86-64,
but it originally was signed when the signal code was written.
And the if (orig_rax >= 0) ended up always true.
And gcc didn't warn about this, because the warning is only in
-Wextra.

In 2.4 we still had a cast for it, but somehow it got dropped
in 2.5.

Credit goes to John Slice for tracking it down and Erich Boleyn
for the original fix. All blame to me. I fixed it at another
place too.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/x86_64/kernel/signal.c

index 8f069cf3d6e94436202e7f5bba7288a229d476be..e9aa2ca0b55dfe405189321154c591893e1fcd15 100644 (file)
@@ -357,7 +357,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 #endif
 
        /* Are we from a system call? */
-       if (regs->orig_rax >= 0) {
+       if ((long)regs->orig_rax >= 0) {
                /* If so, check system call restarting.. */
                switch (regs->rax) {
                        case -ERESTART_RESTARTBLOCK:
@@ -442,7 +442,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
 
  no_signal:
        /* Did we come from a system call? */
-       if (regs->orig_rax >= 0) {
+       if ((long)regs->orig_rax >= 0) {
                /* Restart the system call - no handlers present */
                long res = regs->rax;
                if (res == -ERESTARTNOHAND ||