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
	
	Block a user