]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
x86/spec_ctrl: save IBRS MSR value in paranoid_entry
authorAndrea Arcangeli <aarcange@redhat.com>
Fri, 15 Dec 2017 00:04:25 +0000 (16:04 -0800)
committerKirtikar Kashyap <kirtikar.kashyap@oracle.com>
Fri, 12 Jan 2018 18:19:55 +0000 (10:19 -0800)
If the NMI runs while entering kernel between SWAPGS and IBRS_ENABLE
everything is fine, paranoid_entry would have unconditionally set
IBRS bit 0 and when exiting the NMI it would have cleared bit 0 like
if it was returning to userland. IBRS_ENABLE would have then enabled
bit 0 again.

If NMI instead runs when exiting kernel between IBRS_DISABLE and
SWAPGS, the NMI would have turned on IBRS bit 0 and then it would have
left enabled when exiting the NMI. IBRS bit 0 would then be left
enabled in userland until the next enter kernel.

That is a minor inefficiency only, but we can eliminate it by saving
the MSR when entering the NMI in save_paranoid and restoring it when
exiting the NMI.

Orabug: 27344012
CVE: CVE-2017-5715

Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: John Haxby <john.haxby@oracle.com>
Signed-off-by: Kirtikar Kashyap <kirtikar.kashyap@oracle.com>
arch/x86/include/asm/spec_ctrl.h
arch/x86/kernel/entry_64.S

index 1d313ff9799bb7e882bb28335ae0cb573fab4b7e..712f12deea32c09544b0d3fd004ace464a9e5192 100644 (file)
@@ -65,6 +65,40 @@ ALTERNATIVE "", __stringify(__ASM_ENABLE_IBRS), X86_FEATURE_SPEC_CTRL
 11:
 .endm
 
+.macro ENABLE_IBRS_SAVE_AND_CLOBBER save_reg:req
+       testl   $1, use_ibrs
+       jz      12f
+
+       movl    $MSR_IA32_SPEC_CTRL, %ecx
+       rdmsr
+       movl    %eax, \save_reg
+
+       movl    $0, %edx
+       movl    $FEATURE_ENABLE_IBRS, %eax
+       wrmsr
+       jmp 22f
+12:
+       lfence
+22:
+.endm
+
+.macro RESTORE_IBRS_CLOBBER save_reg:req
+       testl   $1, use_ibrs
+       jz      13f
+
+       cmpl    $FEATURE_ENABLE_IBRS, \save_reg
+       je      13f
+
+       movl    $MSR_IA32_SPEC_CTRL, %ecx
+       movl    $0, %edx
+       movl    \save_reg, %eax
+       wrmsr
+       jmp 23f
+13:
+       lfence
+23:
+.endm
+
 .macro DISABLE_IBRS
 ALTERNATIVE "", __stringify(__ASM_DISABLE_IBRS), X86_FEATURE_SPEC_CTRL
 .endm
index 82148ae50eb1c2d5f397a9bd5fce661beed17d36..157c53c82031ed7e3ac3dc02035f26ff11c4d4ab 100644 (file)
@@ -1437,7 +1437,7 @@ ENTRY(paranoid_entry)
        js 1f   /* negative -> in kernel */
        SWAPGS
        xorl %ebx,%ebx
-1:     ENABLE_IBRS_CLOBBER
+1:     ENABLE_IBRS_SAVE_AND_CLOBBER save_reg=%r13d
        ret
        CFI_ENDPROC
 END(paranoid_entry)
@@ -1460,6 +1460,7 @@ ENTRY(paranoid_exit)
        testl %ebx,%ebx                         /* swapgs needed? */
        jnz paranoid_exit_no_swapgs
        TRACE_IRQS_IRETQ
+       RESTORE_IBRS_CLOBBER save_reg=%r13d
        SWAPGS_UNSAFE_STACK
        jmp paranoid_exit_restore
 paranoid_exit_no_swapgs:
@@ -1864,6 +1865,8 @@ end_repeat_nmi:
        movq $-1,%rsi
        call do_nmi
 
+       RESTORE_IBRS_CLOBBER save_reg=%r13d
+
        testl %ebx,%ebx                         /* swapgs needed? */
        jnz nmi_restore
 nmi_swapgs: