Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8169aff6 authored by Andy Lutomirski's avatar Andy Lutomirski Committed by Ingo Molnar
Browse files

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: default avatarAndy 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: default avatarIngo Molnar <mingo@kernel.org>
parent 2ec67971
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -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

+13 −29
Original line number Diff line number Diff line
@@ -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
+6 −6
Original line number Diff line number Diff line
@@ -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