• Dominik Brodowski's avatar
    syscalls/x86: Use 'struct pt_regs' based syscall calling convention for 64-bit syscalls · fa697140
    Dominik Brodowski authored
    Let's make use of ARCH_HAS_SYSCALL_WRAPPER=y on pure 64-bit x86-64 systems:
    
    Each syscall defines a stub which takes struct pt_regs as its only
    argument. It decodes just those parameters it needs, e.g:
    
    	asmlinkage long sys_xyzzy(const struct pt_regs *regs)
    	{
    		return SyS_xyzzy(regs->di, regs->si, regs->dx);
    	}
    
    This approach avoids leaking random user-provided register content down
    the call chain.
    
    For example, for sys_recv() which is a 4-parameter syscall, the assembly
    now is (in slightly reordered fashion):
    
    	<sys_recv>:
    		callq	<__fentry__>
    
    		/* decode regs->di, ->si, ->dx and ->r10 */
    		mov	0x70(%rdi),%rdi
    		mov	0x68(%rdi),%rsi
    		mov	0x60(%rdi),%rdx
    		mov	0x38(%rdi),%rcx
    
    		[ SyS_recv() is automatically inlined by the compiler,
    		  as it is not [yet] used anywhere else ]
    		/* clear %r9 and %r8, the 5th and 6th args */
    		xor	%r9d,%r9d
    		xor	%r8d,%r8d
    
    		/* do the actual work */
    		callq	__sys_recvfrom
    
    		/* cleanup and return */
    		cltq
    		retq
    
    The only valid place in an x86-64 kernel which rightfully calls
    a syscall function on its own -- vsyscall -- needs to be modified
    to pass struct pt_regs onwards as well.
    
    To keep the syscall table generation working independent of
    SYSCALL_PTREGS being enabled, the stubs are named the same as the
    "original" syscall stubs, i.e. sys_*().
    
    This patch is based on an original proof-of-concept
    
     | From: Linus Torvalds <torvalds@linux-foundation.org>
     | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    
    and was split up and heavily modified by me, in particular to base it on
    ARCH_HAS_SYSCALL_WRAPPER, to limit it to 64-bit-only for the time being,
    and to update the vsyscall to the new calling convention.
    Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
    Acked-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Cc: Andy Lutomirski <luto@kernel.org>
    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: Josh Poimboeuf <jpoimboe@redhat.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Link: http://lkml.kernel.org/r/20180405095307.3730-4-linux@dominikbrodowski.netSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    fa697140
Name
Last commit
Last update
..
alpha Loading commit data...
arc Loading commit data...
arm Loading commit data...
arm64 Loading commit data...
c6x Loading commit data...
h8300 Loading commit data...
hexagon Loading commit data...
ia64 Loading commit data...
m68k Loading commit data...
microblaze Loading commit data...
mips Loading commit data...
nds32 Loading commit data...
nios2 Loading commit data...
openrisc Loading commit data...
parisc Loading commit data...
powerpc Loading commit data...
riscv Loading commit data...
s390 Loading commit data...
sh Loading commit data...
sparc Loading commit data...
um Loading commit data...
unicore32 Loading commit data...
x86 Loading commit data...
xtensa Loading commit data...
.gitignore Loading commit data...
Kconfig Loading commit data...