Commit 552b8aa4d1edcc1c764ff6f61a7686347a2d1827
1 parent
e0a96129db
Exists in
master
and in
4 other branches
Revert "x86: signal: change type of paramter for sys_rt_sigreturn()"
This reverts commit 4217458dafaa57d8e26a46f5d05ab8c53cf64191. Justin Madru bisected this commit, it was causing weird Firefox crashes. The reason is that GCC mis-optimizes (re-uses) the on-stack parameters of the calling frame, which corrupts the syscall return pt_regs state and thus corrupts user-space register state. So we go back to the slightly less clean but more optimization-safe method of getting to pt_regs. Also add a comment to explain this. Resolves: http://bugzilla.kernel.org/show_bug.cgi?id=12505 Reported-and-bisected-by: Justin Madru <jdm64@gawab.com> Tested-by: Justin Madru <jdm64@gawab.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Showing 2 changed files with 10 additions and 3 deletions Side-by-side Diff
arch/x86/include/asm/syscalls.h
... | ... | @@ -40,7 +40,7 @@ |
40 | 40 | struct old_sigaction __user *); |
41 | 41 | asmlinkage int sys_sigaltstack(unsigned long); |
42 | 42 | asmlinkage unsigned long sys_sigreturn(unsigned long); |
43 | -asmlinkage int sys_rt_sigreturn(struct pt_regs); | |
43 | +asmlinkage int sys_rt_sigreturn(unsigned long); | |
44 | 44 | |
45 | 45 | /* kernel/ioport.c */ |
46 | 46 | asmlinkage long sys_iopl(unsigned long); |
arch/x86/kernel/signal.c
... | ... | @@ -632,9 +632,16 @@ |
632 | 632 | } |
633 | 633 | |
634 | 634 | #ifdef CONFIG_X86_32 |
635 | -asmlinkage int sys_rt_sigreturn(struct pt_regs regs) | |
635 | +/* | |
636 | + * Note: do not pass in pt_regs directly as with tail-call optimization | |
637 | + * GCC will incorrectly stomp on the caller's frame and corrupt user-space | |
638 | + * register state: | |
639 | + */ | |
640 | +asmlinkage int sys_rt_sigreturn(unsigned long __unused) | |
636 | 641 | { |
637 | - return do_rt_sigreturn(®s); | |
642 | + struct pt_regs *regs = (struct pt_regs *)&__unused; | |
643 | + | |
644 | + return do_rt_sigreturn(regs); | |
638 | 645 | } |
639 | 646 | #else /* !CONFIG_X86_32 */ |
640 | 647 | asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) |