Commit c33d4568 authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] x86-64: Fix up handling of non canonical user RIPs

EM64T CPUs have somewhat weird error reporting for non canonical RIPs in
SYSRET.

We can't handle any exceptions there because the exception handler would
end up running on the user stack which is unsafe.

To avoid problems any code that might end up with a user touched pt_regs
should return using int_ret_from_syscall.  int_ret_from_syscall ends up
using IRET, which allows safe exceptions.

Cc: Ernie Petrides <petrides@redhat.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 31fe4d33
...@@ -178,6 +178,12 @@ rff_trace: ...@@ -178,6 +178,12 @@ rff_trace:
* Interrupts are off on entry. * Interrupts are off on entry.
* Only called from user space. * Only called from user space.
* *
* EM64T CPUs have somewhat weird error reporting for non canonical RIPs in SYSRET.
* We can't handle any exceptions there because the exception handler would
* end up running on the user stack which is unsafe. To avoid problems
* any code that might end up with a user touched pt_regs should return
* using int_ret_from_syscall.
*
* XXX if we had a free scratch register we could save the RSP into the stack frame * XXX if we had a free scratch register we could save the RSP into the stack frame
* and report it properly in ps. Unfortunately we haven't. * and report it properly in ps. Unfortunately we haven't.
*/ */
...@@ -254,7 +260,9 @@ sysret_signal: ...@@ -254,7 +260,9 @@ sysret_signal:
xorl %esi,%esi # oldset -> arg2 xorl %esi,%esi # oldset -> arg2
call ptregscall_common call ptregscall_common
1: movl $_TIF_NEED_RESCHED,%edi 1: movl $_TIF_NEED_RESCHED,%edi
jmp sysret_check /* Stack frame might have been changed. The IRET path does
some additional checks to handle this */
jmp int_with_check
badsys: badsys:
movq $-ENOSYS,RAX-ARGOFFSET(%rsp) movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
...@@ -280,7 +288,8 @@ tracesys: ...@@ -280,7 +288,8 @@ tracesys:
call syscall_trace_leave call syscall_trace_leave
RESTORE_TOP_OF_STACK %rbx RESTORE_TOP_OF_STACK %rbx
RESTORE_REST RESTORE_REST
jmp ret_from_sys_call /* Stack frame might have been changed. Use the more careful IRET path */
jmp int_ret_from_sys_call
CFI_ENDPROC CFI_ENDPROC
/* /*
...@@ -408,25 +417,9 @@ ENTRY(stub_execve) ...@@ -408,25 +417,9 @@ ENTRY(stub_execve)
CFI_ADJUST_CFA_OFFSET -8 CFI_ADJUST_CFA_OFFSET -8
CFI_REGISTER rip, r11 CFI_REGISTER rip, r11
SAVE_REST SAVE_REST
movq %r11, %r15
CFI_REGISTER rip, r15
FIXUP_TOP_OF_STACK %r11 FIXUP_TOP_OF_STACK %r11
call sys_execve call sys_execve
GET_THREAD_INFO(%rcx)
bt $TIF_IA32,threadinfo_flags(%rcx)
CFI_REMEMBER_STATE
jc exec_32bit
RESTORE_TOP_OF_STACK %r11 RESTORE_TOP_OF_STACK %r11
movq %r15, %r11
CFI_REGISTER rip, r11
RESTORE_REST
pushq %r11
CFI_ADJUST_CFA_OFFSET 8
CFI_REL_OFFSET rip, 0
ret
exec_32bit:
CFI_RESTORE_STATE
movq %rax,RAX(%rsp) movq %rax,RAX(%rsp)
RESTORE_REST RESTORE_REST
jmp int_ret_from_sys_call jmp int_ret_from_sys_call
......
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