Skip to content

Commit 22eab11

Browse files
ldv-altKAGA-KOKO
authored andcommitted
x86/signal: Fix restart_syscall number for x32 tasks
When restarting a syscall with regs->ax == -ERESTART_RESTARTBLOCK, regs->ax is assigned to a restart_syscall number. For x32 tasks, this syscall number must have __X32_SYSCALL_BIT set, otherwise it will be an x86_64 syscall number instead of a valid x32 syscall number. This issue has been there since the introduction of x32. Reported-by: strace/tests/restart_syscall.test Reported-and-tested-by: Elvira Khabirova <lineprinter0@gmail.com> Signed-off-by: Dmitry V. Levin <ldv@altlinux.org> Cc: Elvira Khabirova <lineprinter0@gmail.com> Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20151130215436.GA25996@altlinux.org Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
1 parent 8e8efe0 commit 22eab11

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

arch/x86/kernel/signal.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -690,12 +690,15 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
690690
signal_setup_done(failed, ksig, stepping);
691691
}
692692

693-
#ifdef CONFIG_X86_32
694-
#define NR_restart_syscall __NR_restart_syscall
695-
#else /* !CONFIG_X86_32 */
696-
#define NR_restart_syscall \
697-
test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall
698-
#endif /* CONFIG_X86_32 */
693+
static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs)
694+
{
695+
#if defined(CONFIG_X86_32) || !defined(CONFIG_X86_64)
696+
return __NR_restart_syscall;
697+
#else /* !CONFIG_X86_32 && CONFIG_X86_64 */
698+
return test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall :
699+
__NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT);
700+
#endif /* CONFIG_X86_32 || !CONFIG_X86_64 */
701+
}
699702

700703
/*
701704
* Note that 'init' is a special process: it doesn't get signals it doesn't
@@ -724,7 +727,7 @@ void do_signal(struct pt_regs *regs)
724727
break;
725728

726729
case -ERESTART_RESTARTBLOCK:
727-
regs->ax = NR_restart_syscall;
730+
regs->ax = get_nr_restart_syscall(regs);
728731
regs->ip -= 2;
729732
break;
730733
}

0 commit comments

Comments
 (0)