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>
#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:
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 ||