Skip to content

Commit 8e1eb3f

Browse files
djbwIngo Molnar
authored andcommitted
x86/entry/64: Clear extra registers beyond syscall arguments, to reduce speculation attack surface
At entry userspace may have (maliciously) populated the extra registers outside the syscall calling convention with arbitrary values that could be useful in a speculative execution (Spectre style) attack. Clear these registers to minimize the kernel's attack surface. Note, this only clears the extra registers and not the unused registers for syscalls less than 6 arguments, since those registers are likely to be clobbered well before their values could be put to use under speculation. Note, Linus found that the XOR instructions can be executed with minimized cost if interleaved with the PUSH instructions, and Ingo's analysis found that R10 and R11 should be included in the register clearing beyond the typical 'extra' syscall calling convention registers. Suggested-by: Linus Torvalds <[email protected]> Reported-by: Andi Kleen <[email protected]> Signed-off-by: Dan Williams <[email protected]> Cc: <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Link: http://lkml.kernel.org/r/151787988577.7847.16733592218894189003.stgit@dwillia2-desk3.amr.corp.intel.com [ Made small improvements to the changelog and the code comments. ] Signed-off-by: Ingo Molnar <[email protected]>
1 parent b2ac58f commit 8e1eb3f

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

arch/x86/entry/entry_64.S

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,26 @@ GLOBAL(entry_SYSCALL_64_after_hwframe)
235235
pushq %r8 /* pt_regs->r8 */
236236
pushq %r9 /* pt_regs->r9 */
237237
pushq %r10 /* pt_regs->r10 */
238+
/*
239+
* Clear extra registers that a speculation attack might
240+
* otherwise want to exploit. Interleave XOR with PUSH
241+
* for better uop scheduling:
242+
*/
243+
xorq %r10, %r10 /* nospec r10 */
238244
pushq %r11 /* pt_regs->r11 */
245+
xorq %r11, %r11 /* nospec r11 */
239246
pushq %rbx /* pt_regs->rbx */
247+
xorl %ebx, %ebx /* nospec rbx */
240248
pushq %rbp /* pt_regs->rbp */
249+
xorl %ebp, %ebp /* nospec rbp */
241250
pushq %r12 /* pt_regs->r12 */
251+
xorq %r12, %r12 /* nospec r12 */
242252
pushq %r13 /* pt_regs->r13 */
253+
xorq %r13, %r13 /* nospec r13 */
243254
pushq %r14 /* pt_regs->r14 */
255+
xorq %r14, %r14 /* nospec r14 */
244256
pushq %r15 /* pt_regs->r15 */
257+
xorq %r15, %r15 /* nospec r15 */
245258
UNWIND_HINT_REGS
246259

247260
TRACE_IRQS_OFF

0 commit comments

Comments
 (0)