aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2018-04-05 05:53:06 -0400
committerIngo Molnar <mingo@kernel.org>2018-04-05 10:59:39 -0400
commit6dc936f175cc6d12a8eb14d29b87e9238e460383 (patch)
treeb2a745b9761a0224da7adb2fbd7a40131c347a7b
parentf8781c4a226319fe60e652118b90cf094ccfe747 (diff)
syscalls/x86: Extend register clearing on syscall entry to lower registers
To reduce the chance that random user space content leaks down the call chain in registers, also clear lower registers on syscall entry: For 64-bit syscalls, extend the register clearing in PUSH_AND_CLEAR_REGS to %dx and %cx. This should not hurt at all, also on the other callers of that macro. We do not need to clear %rdi and %rsi for syscall entry, as those registers are used to pass the parameters to do_syscall_64(). For the 32-bit compat syscalls, do_int80_syscall_32() and do_fast_syscall_32() each only take one parameter. Therefore, extend the register clearing to %dx, %cx, and %si in entry_SYSCALL_compat and entry_INT80_compat. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net> Acked-by: Linus 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-8-linux@dominikbrodowski.net Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/entry/calling.h2
-rw-r--r--arch/x86/entry/entry_64_compat.S6
2 files changed, 8 insertions, 0 deletions
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index be63330c5511..352e70cd33e8 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -114,7 +114,9 @@ For 32-bit we have the following conventions - kernel is built with
114 pushq %rsi /* pt_regs->si */ 114 pushq %rsi /* pt_regs->si */
115 .endif 115 .endif
116 pushq \rdx /* pt_regs->dx */ 116 pushq \rdx /* pt_regs->dx */
117 xorl %edx, %edx /* nospec dx */
117 pushq %rcx /* pt_regs->cx */ 118 pushq %rcx /* pt_regs->cx */
119 xorl %ecx, %ecx /* nospec cx */
118 pushq \rax /* pt_regs->ax */ 120 pushq \rax /* pt_regs->ax */
119 pushq %r8 /* pt_regs->r8 */ 121 pushq %r8 /* pt_regs->r8 */
120 xorl %r8d, %r8d /* nospec r8 */ 122 xorl %r8d, %r8d /* nospec r8 */
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index 08425c42f8b7..9af927e59d49 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -220,8 +220,11 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe)
220 pushq %rax /* pt_regs->orig_ax */ 220 pushq %rax /* pt_regs->orig_ax */
221 pushq %rdi /* pt_regs->di */ 221 pushq %rdi /* pt_regs->di */
222 pushq %rsi /* pt_regs->si */ 222 pushq %rsi /* pt_regs->si */
223 xorl %esi, %esi /* nospec si */
223 pushq %rdx /* pt_regs->dx */ 224 pushq %rdx /* pt_regs->dx */
225 xorl %edx, %edx /* nospec dx */
224 pushq %rbp /* pt_regs->cx (stashed in bp) */ 226 pushq %rbp /* pt_regs->cx (stashed in bp) */
227 xorl %ecx, %ecx /* nospec cx */
225 pushq $-ENOSYS /* pt_regs->ax */ 228 pushq $-ENOSYS /* pt_regs->ax */
226 pushq $0 /* pt_regs->r8 = 0 */ 229 pushq $0 /* pt_regs->r8 = 0 */
227 xorl %r8d, %r8d /* nospec r8 */ 230 xorl %r8d, %r8d /* nospec r8 */
@@ -365,8 +368,11 @@ ENTRY(entry_INT80_compat)
365 368
366 pushq (%rdi) /* pt_regs->di */ 369 pushq (%rdi) /* pt_regs->di */
367 pushq %rsi /* pt_regs->si */ 370 pushq %rsi /* pt_regs->si */
371 xorl %esi, %esi /* nospec si */
368 pushq %rdx /* pt_regs->dx */ 372 pushq %rdx /* pt_regs->dx */
373 xorl %edx, %edx /* nospec dx */
369 pushq %rcx /* pt_regs->cx */ 374 pushq %rcx /* pt_regs->cx */
375 xorl %ecx, %ecx /* nospec cx */
370 pushq $-ENOSYS /* pt_regs->ax */ 376 pushq $-ENOSYS /* pt_regs->ax */
371 pushq $0 /* pt_regs->r8 = 0 */ 377 pushq $0 /* pt_regs->r8 = 0 */
372 xorl %r8d, %r8d /* nospec r8 */ 378 xorl %r8d, %r8d /* nospec r8 */