After a NMI from userland, the kernel is entered and it switches the stack to the PTI stack which is mapped both in the kernel and in the user page-table. When executing the NMI handler, switch to the kernel stack (which is mapped only in the kernel page-table) so that no kernel data leak to the userland through the stack.
Signed-off-by: Alexandre Chartre <alexandre.char...@oracle.com> --- arch/x86/kernel/nmi.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 4bc77aaf1303..be0f654c3095 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -506,8 +506,18 @@ DEFINE_IDTENTRY_RAW(exc_nmi) inc_irq_stat(__nmi_count); - if (!ignore_nmis) - default_do_nmi(regs); + if (!ignore_nmis) { + if (user_mode(regs)) { + /* + * If we come from userland then we are on the + * trampoline stack, switch to the kernel stack + * to execute the NMI handler. + */ + run_idt(default_do_nmi, regs); + } else { + default_do_nmi(regs); + } + } idtentry_exit_nmi(regs, irq_state); -- 2.18.4