[PATCH 175/208] x86/fpu: Clean up fpu__clear() state handling

From: Ingo Molnar
Date: Tue May 05 2015 - 14:12:48 EST


We currently leak FPU state across execve() boundaries on eagerfpu systems:

$ /host/home/mingo/dump-xmm-regs-exec
# XMM state before execve():
XMM0 : 000000000000dede
XMM1 : 000000000000dedf
XMM2 : 000000000000dee0
XMM3 : 000000000000dee1
XMM4 : 000000000000dee2
XMM5 : 000000000000dee3
XMM6 : 000000000000dee4
XMM7 : 000000000000dee5
XMM8 : 000000000000dee6
XMM9 : 000000000000dee7
XMM10: 000000000000dee8
XMM11: 000000000000dee9
XMM12: 000000000000deea
XMM13: 000000000000deeb
XMM14: 000000000000deec
XMM15: 000000000000deed

# XMM state after execve(), in the new task context:
XMM0 : 0000000000000000
XMM1 : 2f2f2f2f2f2f2f2f
XMM2 : 0000000000000000
XMM3 : 0000000000000000
XMM4 : 00000000000000ff
XMM5 : 00000000ff000000
XMM6 : 000000000000dee4
XMM7 : 000000000000dee5
XMM8 : 0000000000000000
XMM9 : 0000000000000000
XMM10: 0000000000000000
XMM11: 0000000000000000
XMM12: 0000000000000000
XMM13: 000000000000deeb
XMM14: 000000000000deec
XMM15: 000000000000deed

The reason is that fpu__clear() does not clear out the state properly.

Fix it.

Cc: Andy Lutomirski <luto@xxxxxxxxxxxxxx>
Cc: Borislav Petkov <bp@xxxxxxxxx>
Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>
Cc: Fenghua Yu <fenghua.yu@xxxxxxxxx>
Cc: H. Peter Anvin <hpa@xxxxxxxxx>
Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Cc: Oleg Nesterov <oleg@xxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx>
---
arch/x86/kernel/fpu/core.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index 45ef4e51928b..33c9a43b000e 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -348,6 +348,10 @@ void fpu__restore(void)
}
EXPORT_SYMBOL_GPL(fpu__restore);

+/*
+ * Called by sys_execve() to clear the FPU fpregs, so that FPU state
+ * of the previous binary does not leak over into the exec()ed binary:
+ */
void fpu__clear(struct task_struct *tsk)
{
struct fpu *fpu = &tsk->thread.fpu;
@@ -361,8 +365,8 @@ void fpu__clear(struct task_struct *tsk)
if (!fpu->fpstate_active) {
fpu__activate_curr(fpu);
user_fpu_begin();
- restore_init_xstate();
}
+ restore_init_xstate();
}
}

--
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/