From 718fd007a635d32df8ca3ff5fe5e13f76a4ea041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Dziepak?= Date: Sun, 14 Sep 2014 19:02:27 +0200 Subject: [PATCH] kernel/x86_64: clear xmm0-15 registers on syscall exit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As Alex pointed out we can leak possibly sensitive data in xmm registers when returning from the kernel. To prevent that xmm0-15 are zeroed before sysret or iret. The cost is negligible. Signed-off-by: Paweł Dziepak --- src/system/kernel/arch/x86/64/interrupts.S | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/system/kernel/arch/x86/64/interrupts.S b/src/system/kernel/arch/x86/64/interrupts.S index 50ba3ea384..c94f0d8dc9 100644 --- a/src/system/kernel/arch/x86/64/interrupts.S +++ b/src/system/kernel/arch/x86/64/interrupts.S @@ -118,6 +118,23 @@ call x86_exit_user_debug_at_kernel_entry; \ 1: +#define CLEAR_FPU_STATE() \ + pxor %xmm0, %xmm0; \ + pxor %xmm1, %xmm1; \ + pxor %xmm2, %xmm2; \ + pxor %xmm3, %xmm3; \ + pxor %xmm4, %xmm4; \ + pxor %xmm5, %xmm5; \ + pxor %xmm6, %xmm6; \ + pxor %xmm7, %xmm7; \ + pxor %xmm8, %xmm8; \ + pxor %xmm9, %xmm9; \ + pxor %xmm10, %xmm10; \ + pxor %xmm11, %xmm11; \ + pxor %xmm12, %xmm12; \ + pxor %xmm13, %xmm13; \ + pxor %xmm14, %xmm14; \ + pxor %xmm15, %xmm15 // The following code defines the interrupt service routines for all 256 // interrupts. It creates a block of handlers, each 16 bytes, that the IDT @@ -416,6 +433,8 @@ FUNCTION(x86_64_syscall_entry): cmpq $SYSCALL_RESTORE_SIGNAL_FRAME, %r14 je .Lrestore_fpu + CLEAR_FPU_STATE() + // Restore the iframe and RCX/R11 for SYSRET. RESTORE_IFRAME() pop %rcx @@ -478,13 +497,14 @@ FUNCTION(x86_64_syscall_entry): 1: // Install breakpoints, if defined. testl $THREAD_FLAGS_BREAKPOINTS_DEFINED, THREAD_flags(%r12) - jz .Liret + jz 1f movq %rbp, %rdi call x86_init_user_debug_at_kernel_exit - +1: // On this return path it is possible that the frame has been modified, // for example to execute a signal handler. In this case it is safer to // return via IRET. + CLEAR_FPU_STATE() jmp .Liret .Lrestore_fpu: