x86/entry/64/compat: Set up full pt_regs for all compat syscalls
This is conceptually simpler. More importantly, it eliminates the PTREGSCALL and execve stubs, which were not compatible with the C ABI. This means that C code can call through the compat syscall table. The execve stubs are a bit subtle. They did two things: they cleared some registers and they forced slow-path return. Neither is necessary any more: elf_common_init clears the extra registers and start_thread calls force_iret(). Signed-off-by: Andy Lutomirski <luto@kernel.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-kernel@vger.kernel.org Link: http://lkml.kernel.org/r/f95b7f7dfaacf88a8cae85bb06226cae53769287.1444091584.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
2ec67971fa
commit
8169aff611
|
@ -391,20 +391,16 @@ GLOBAL(stub_execveat)
|
|||
jmp return_from_execve
|
||||
END(stub_execveat)
|
||||
|
||||
#if defined(CONFIG_X86_X32_ABI) || defined(CONFIG_IA32_EMULATION)
|
||||
#if defined(CONFIG_X86_X32_ABI)
|
||||
.align 8
|
||||
GLOBAL(stub_x32_execve)
|
||||
GLOBAL(stub32_execve)
|
||||
call compat_sys_execve
|
||||
jmp return_from_execve
|
||||
END(stub32_execve)
|
||||
END(stub_x32_execve)
|
||||
.align 8
|
||||
GLOBAL(stub_x32_execveat)
|
||||
GLOBAL(stub32_execveat)
|
||||
call compat_sys_execveat
|
||||
jmp return_from_execve
|
||||
END(stub32_execveat)
|
||||
END(stub_x32_execveat)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -219,12 +219,18 @@ ENTRY(entry_INT80_compat)
|
|||
pushq %rdx /* pt_regs->dx */
|
||||
pushq %rcx /* pt_regs->cx */
|
||||
pushq $-ENOSYS /* pt_regs->ax */
|
||||
pushq $0 /* pt_regs->r8 */
|
||||
pushq $0 /* pt_regs->r9 */
|
||||
pushq $0 /* pt_regs->r10 */
|
||||
pushq $0 /* pt_regs->r11 */
|
||||
xorq %r8,%r8
|
||||
pushq %r8 /* pt_regs->r8 = 0 */
|
||||
pushq %r8 /* pt_regs->r9 = 0 */
|
||||
pushq %r8 /* pt_regs->r10 = 0 */
|
||||
pushq %r8 /* pt_regs->r11 = 0 */
|
||||
pushq %rbx /* pt_regs->rbx */
|
||||
pushq %rbp /* pt_regs->rbp */
|
||||
pushq %r12 /* pt_regs->r12 */
|
||||
pushq %r13 /* pt_regs->r13 */
|
||||
pushq %r14 /* pt_regs->r14 */
|
||||
pushq %r15 /* pt_regs->r15 */
|
||||
cld
|
||||
sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */
|
||||
|
||||
orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
|
||||
testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
|
||||
|
@ -243,10 +249,10 @@ ia32_do_call:
|
|||
call *ia32_sys_call_table(, %rax, 8)
|
||||
movq %rax, RAX(%rsp)
|
||||
1:
|
||||
RESTORE_EXTRA_REGS
|
||||
jmp int_ret_from_sys_call
|
||||
|
||||
ia32_tracesys:
|
||||
SAVE_EXTRA_REGS
|
||||
movq %rsp, %rdi /* &pt_regs -> arg1 */
|
||||
call syscall_trace_enter
|
||||
/*
|
||||
|
@ -261,25 +267,11 @@ ia32_tracesys:
|
|||
movl RSI(%rsp), %esi
|
||||
movl RDI(%rsp), %edi
|
||||
movl %eax, %eax /* zero extension */
|
||||
RESTORE_EXTRA_REGS
|
||||
jmp ia32_do_call
|
||||
END(entry_INT80_compat)
|
||||
|
||||
.macro PTREGSCALL label, func
|
||||
ALIGN
|
||||
GLOBAL(\label)
|
||||
leaq \func(%rip), %rax
|
||||
jmp ia32_ptregs_common
|
||||
.endm
|
||||
|
||||
PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn
|
||||
PTREGSCALL stub32_sigreturn, sys32_sigreturn
|
||||
PTREGSCALL stub32_fork, sys_fork
|
||||
PTREGSCALL stub32_vfork, sys_vfork
|
||||
|
||||
ALIGN
|
||||
GLOBAL(stub32_clone)
|
||||
leaq sys_clone(%rip), %rax
|
||||
/*
|
||||
* The 32-bit clone ABI is: clone(..., int tls_val, int *child_tidptr).
|
||||
* The 64-bit clone ABI is: clone(..., int *child_tidptr, int tls_val).
|
||||
|
@ -288,12 +280,4 @@ GLOBAL(stub32_clone)
|
|||
* so we need to swap arguments here before calling it:
|
||||
*/
|
||||
xchg %r8, %rcx
|
||||
jmp ia32_ptregs_common
|
||||
|
||||
ALIGN
|
||||
ia32_ptregs_common:
|
||||
SAVE_EXTRA_REGS 8
|
||||
call *%rax
|
||||
RESTORE_EXTRA_REGS 8
|
||||
ret
|
||||
END(ia32_ptregs_common)
|
||||
jmp sys_clone
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#
|
||||
0 i386 restart_syscall sys_restart_syscall
|
||||
1 i386 exit sys_exit
|
||||
2 i386 fork sys_fork stub32_fork
|
||||
2 i386 fork sys_fork sys_fork
|
||||
3 i386 read sys_read
|
||||
4 i386 write sys_write
|
||||
5 i386 open sys_open compat_sys_open
|
||||
|
@ -17,7 +17,7 @@
|
|||
8 i386 creat sys_creat
|
||||
9 i386 link sys_link
|
||||
10 i386 unlink sys_unlink
|
||||
11 i386 execve sys_execve stub32_execve
|
||||
11 i386 execve sys_execve compat_sys_execve
|
||||
12 i386 chdir sys_chdir
|
||||
13 i386 time sys_time compat_sys_time
|
||||
14 i386 mknod sys_mknod
|
||||
|
@ -125,7 +125,7 @@
|
|||
116 i386 sysinfo sys_sysinfo compat_sys_sysinfo
|
||||
117 i386 ipc sys_ipc compat_sys_ipc
|
||||
118 i386 fsync sys_fsync
|
||||
119 i386 sigreturn sys_sigreturn stub32_sigreturn
|
||||
119 i386 sigreturn sys_sigreturn sys32_sigreturn
|
||||
120 i386 clone sys_clone stub32_clone
|
||||
121 i386 setdomainname sys_setdomainname
|
||||
122 i386 uname sys_newuname
|
||||
|
@ -179,7 +179,7 @@
|
|||
170 i386 setresgid sys_setresgid16
|
||||
171 i386 getresgid sys_getresgid16
|
||||
172 i386 prctl sys_prctl
|
||||
173 i386 rt_sigreturn sys_rt_sigreturn stub32_rt_sigreturn
|
||||
173 i386 rt_sigreturn sys_rt_sigreturn sys32_rt_sigreturn
|
||||
174 i386 rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction
|
||||
175 i386 rt_sigprocmask sys_rt_sigprocmask
|
||||
176 i386 rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending
|
||||
|
@ -196,7 +196,7 @@
|
|||
187 i386 sendfile sys_sendfile compat_sys_sendfile
|
||||
188 i386 getpmsg
|
||||
189 i386 putpmsg
|
||||
190 i386 vfork sys_vfork stub32_vfork
|
||||
190 i386 vfork sys_vfork sys_vfork
|
||||
191 i386 ugetrlimit sys_getrlimit compat_sys_getrlimit
|
||||
192 i386 mmap2 sys_mmap_pgoff
|
||||
193 i386 truncate64 sys_truncate64 sys32_truncate64
|
||||
|
@ -364,7 +364,7 @@
|
|||
355 i386 getrandom sys_getrandom
|
||||
356 i386 memfd_create sys_memfd_create
|
||||
357 i386 bpf sys_bpf
|
||||
358 i386 execveat sys_execveat stub32_execveat
|
||||
358 i386 execveat sys_execveat compat_sys_execveat
|
||||
359 i386 socket sys_socket
|
||||
360 i386 socketpair sys_socketpair
|
||||
361 i386 bind sys_bind
|
||||
|
|
Loading…
Reference in New Issue