Commit 0233f53f authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] x86_64: fix syscall/signal restart bug

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: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 39509e47
......@@ -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 ||
......
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