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
3 changed files with 20 additions and 40 deletions
|
@ -391,20 +391,16 @@ GLOBAL(stub_execveat)
|
||||||
jmp return_from_execve
|
jmp return_from_execve
|
||||||
END(stub_execveat)
|
END(stub_execveat)
|
||||||
|
|
||||||
#if defined(CONFIG_X86_X32_ABI) || defined(CONFIG_IA32_EMULATION)
|
#if defined(CONFIG_X86_X32_ABI)
|
||||||
.align 8
|
.align 8
|
||||||
GLOBAL(stub_x32_execve)
|
GLOBAL(stub_x32_execve)
|
||||||
GLOBAL(stub32_execve)
|
|
||||||
call compat_sys_execve
|
call compat_sys_execve
|
||||||
jmp return_from_execve
|
jmp return_from_execve
|
||||||
END(stub32_execve)
|
|
||||||
END(stub_x32_execve)
|
END(stub_x32_execve)
|
||||||
.align 8
|
.align 8
|
||||||
GLOBAL(stub_x32_execveat)
|
GLOBAL(stub_x32_execveat)
|
||||||
GLOBAL(stub32_execveat)
|
|
||||||
call compat_sys_execveat
|
call compat_sys_execveat
|
||||||
jmp return_from_execve
|
jmp return_from_execve
|
||||||
END(stub32_execveat)
|
|
||||||
END(stub_x32_execveat)
|
END(stub_x32_execveat)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -219,12 +219,18 @@ ENTRY(entry_INT80_compat)
|
||||||
pushq %rdx /* pt_regs->dx */
|
pushq %rdx /* pt_regs->dx */
|
||||||
pushq %rcx /* pt_regs->cx */
|
pushq %rcx /* pt_regs->cx */
|
||||||
pushq $-ENOSYS /* pt_regs->ax */
|
pushq $-ENOSYS /* pt_regs->ax */
|
||||||
pushq $0 /* pt_regs->r8 */
|
xorq %r8,%r8
|
||||||
pushq $0 /* pt_regs->r9 */
|
pushq %r8 /* pt_regs->r8 = 0 */
|
||||||
pushq $0 /* pt_regs->r10 */
|
pushq %r8 /* pt_regs->r9 = 0 */
|
||||||
pushq $0 /* pt_regs->r11 */
|
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
|
cld
|
||||||
sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */
|
|
||||||
|
|
||||||
orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
|
orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
|
||||||
testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %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)
|
call *ia32_sys_call_table(, %rax, 8)
|
||||||
movq %rax, RAX(%rsp)
|
movq %rax, RAX(%rsp)
|
||||||
1:
|
1:
|
||||||
|
RESTORE_EXTRA_REGS
|
||||||
jmp int_ret_from_sys_call
|
jmp int_ret_from_sys_call
|
||||||
|
|
||||||
ia32_tracesys:
|
ia32_tracesys:
|
||||||
SAVE_EXTRA_REGS
|
|
||||||
movq %rsp, %rdi /* &pt_regs -> arg1 */
|
movq %rsp, %rdi /* &pt_regs -> arg1 */
|
||||||
call syscall_trace_enter
|
call syscall_trace_enter
|
||||||
/*
|
/*
|
||||||
|
@ -261,25 +267,11 @@ ia32_tracesys:
|
||||||
movl RSI(%rsp), %esi
|
movl RSI(%rsp), %esi
|
||||||
movl RDI(%rsp), %edi
|
movl RDI(%rsp), %edi
|
||||||
movl %eax, %eax /* zero extension */
|
movl %eax, %eax /* zero extension */
|
||||||
RESTORE_EXTRA_REGS
|
|
||||||
jmp ia32_do_call
|
jmp ia32_do_call
|
||||||
END(entry_INT80_compat)
|
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
|
ALIGN
|
||||||
GLOBAL(stub32_clone)
|
GLOBAL(stub32_clone)
|
||||||
leaq sys_clone(%rip), %rax
|
|
||||||
/*
|
/*
|
||||||
* The 32-bit clone ABI is: clone(..., int tls_val, int *child_tidptr).
|
* 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).
|
* 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:
|
* so we need to swap arguments here before calling it:
|
||||||
*/
|
*/
|
||||||
xchg %r8, %rcx
|
xchg %r8, %rcx
|
||||||
jmp ia32_ptregs_common
|
jmp sys_clone
|
||||||
|
|
||||||
ALIGN
|
|
||||||
ia32_ptregs_common:
|
|
||||||
SAVE_EXTRA_REGS 8
|
|
||||||
call *%rax
|
|
||||||
RESTORE_EXTRA_REGS 8
|
|
||||||
ret
|
|
||||||
END(ia32_ptregs_common)
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#
|
#
|
||||||
0 i386 restart_syscall sys_restart_syscall
|
0 i386 restart_syscall sys_restart_syscall
|
||||||
1 i386 exit sys_exit
|
1 i386 exit sys_exit
|
||||||
2 i386 fork sys_fork stub32_fork
|
2 i386 fork sys_fork sys_fork
|
||||||
3 i386 read sys_read
|
3 i386 read sys_read
|
||||||
4 i386 write sys_write
|
4 i386 write sys_write
|
||||||
5 i386 open sys_open compat_sys_open
|
5 i386 open sys_open compat_sys_open
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
8 i386 creat sys_creat
|
8 i386 creat sys_creat
|
||||||
9 i386 link sys_link
|
9 i386 link sys_link
|
||||||
10 i386 unlink sys_unlink
|
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
|
12 i386 chdir sys_chdir
|
||||||
13 i386 time sys_time compat_sys_time
|
13 i386 time sys_time compat_sys_time
|
||||||
14 i386 mknod sys_mknod
|
14 i386 mknod sys_mknod
|
||||||
|
@ -125,7 +125,7 @@
|
||||||
116 i386 sysinfo sys_sysinfo compat_sys_sysinfo
|
116 i386 sysinfo sys_sysinfo compat_sys_sysinfo
|
||||||
117 i386 ipc sys_ipc compat_sys_ipc
|
117 i386 ipc sys_ipc compat_sys_ipc
|
||||||
118 i386 fsync sys_fsync
|
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
|
120 i386 clone sys_clone stub32_clone
|
||||||
121 i386 setdomainname sys_setdomainname
|
121 i386 setdomainname sys_setdomainname
|
||||||
122 i386 uname sys_newuname
|
122 i386 uname sys_newuname
|
||||||
|
@ -179,7 +179,7 @@
|
||||||
170 i386 setresgid sys_setresgid16
|
170 i386 setresgid sys_setresgid16
|
||||||
171 i386 getresgid sys_getresgid16
|
171 i386 getresgid sys_getresgid16
|
||||||
172 i386 prctl sys_prctl
|
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
|
174 i386 rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction
|
||||||
175 i386 rt_sigprocmask sys_rt_sigprocmask
|
175 i386 rt_sigprocmask sys_rt_sigprocmask
|
||||||
176 i386 rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending
|
176 i386 rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending
|
||||||
|
@ -196,7 +196,7 @@
|
||||||
187 i386 sendfile sys_sendfile compat_sys_sendfile
|
187 i386 sendfile sys_sendfile compat_sys_sendfile
|
||||||
188 i386 getpmsg
|
188 i386 getpmsg
|
||||||
189 i386 putpmsg
|
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
|
191 i386 ugetrlimit sys_getrlimit compat_sys_getrlimit
|
||||||
192 i386 mmap2 sys_mmap_pgoff
|
192 i386 mmap2 sys_mmap_pgoff
|
||||||
193 i386 truncate64 sys_truncate64 sys32_truncate64
|
193 i386 truncate64 sys_truncate64 sys32_truncate64
|
||||||
|
@ -364,7 +364,7 @@
|
||||||
355 i386 getrandom sys_getrandom
|
355 i386 getrandom sys_getrandom
|
||||||
356 i386 memfd_create sys_memfd_create
|
356 i386 memfd_create sys_memfd_create
|
||||||
357 i386 bpf sys_bpf
|
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
|
359 i386 socket sys_socket
|
||||||
360 i386 socketpair sys_socketpair
|
360 i386 socketpair sys_socketpair
|
||||||
361 i386 bind sys_bind
|
361 i386 bind sys_bind
|
||||||
|
|
Loading…
Add table
Reference in a new issue