mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-22 17:01:14 +00:00
x86/entry/64: Fix unwind hints in register clearing code
[ Upstream commit06a9750edc
] The PUSH_AND_CLEAR_REGS macro zeroes each register immediately after pushing it. If an NMI or exception hits after a register is cleared, but before the UNWIND_HINT_REGS annotation, the ORC unwinder will wrongly think the previous value of the register was zero. This can confuse the unwinding process and cause it to exit early. Because ORC is simpler than DWARF, there are a limited number of unwind annotation states, so it's not possible to add an individual unwind hint after each push/clear combination. Instead, the register clearing instructions need to be consolidated and moved to after the UNWIND_HINT_REGS annotation. Fixes:3f01daecd5
("x86/entry/64: Introduce the PUSH_AND_CLEAN_REGS macro") Reviewed-by: Miroslav Benes <mbenes@suse.cz> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Dave Jones <dsj@fb.com> Cc: Jann Horn <jannh@google.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vince Weaver <vincent.weaver@maine.edu> Link: https://lore.kernel.org/r/68fd3d0bc92ae2d62ff7879d15d3684217d51f08.1587808742.git.jpoimboe@redhat.com Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
336322e8b5
commit
efd9381d62
1 changed files with 21 additions and 17 deletions
|
@ -98,13 +98,6 @@ For 32-bit we have the following conventions - kernel is built with
|
|||
#define SIZEOF_PTREGS 21*8
|
||||
|
||||
.macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax save_ret=0
|
||||
/*
|
||||
* Push registers and sanitize registers of values that a
|
||||
* speculation attack might otherwise want to exploit. The
|
||||
* lower registers are likely clobbered well before they
|
||||
* could be put to use in a speculative execution gadget.
|
||||
* Interleave XOR with PUSH for better uop scheduling:
|
||||
*/
|
||||
.if \save_ret
|
||||
pushq %rsi /* pt_regs->si */
|
||||
movq 8(%rsp), %rsi /* temporarily store the return address in %rsi */
|
||||
|
@ -117,29 +110,40 @@ For 32-bit we have the following conventions - kernel is built with
|
|||
pushq %rcx /* pt_regs->cx */
|
||||
pushq \rax /* pt_regs->ax */
|
||||
pushq %r8 /* pt_regs->r8 */
|
||||
xorl %r8d, %r8d /* nospec r8 */
|
||||
pushq %r9 /* pt_regs->r9 */
|
||||
xorl %r9d, %r9d /* nospec r9 */
|
||||
pushq %r10 /* pt_regs->r10 */
|
||||
xorl %r10d, %r10d /* nospec r10 */
|
||||
pushq %r11 /* pt_regs->r11 */
|
||||
xorl %r11d, %r11d /* nospec r11*/
|
||||
pushq %rbx /* pt_regs->rbx */
|
||||
xorl %ebx, %ebx /* nospec rbx*/
|
||||
pushq %rbp /* pt_regs->rbp */
|
||||
xorl %ebp, %ebp /* nospec rbp*/
|
||||
pushq %r12 /* pt_regs->r12 */
|
||||
xorl %r12d, %r12d /* nospec r12*/
|
||||
pushq %r13 /* pt_regs->r13 */
|
||||
xorl %r13d, %r13d /* nospec r13*/
|
||||
pushq %r14 /* pt_regs->r14 */
|
||||
xorl %r14d, %r14d /* nospec r14*/
|
||||
pushq %r15 /* pt_regs->r15 */
|
||||
xorl %r15d, %r15d /* nospec r15*/
|
||||
UNWIND_HINT_REGS
|
||||
|
||||
.if \save_ret
|
||||
pushq %rsi /* return address on top of stack */
|
||||
.endif
|
||||
|
||||
/*
|
||||
* Sanitize registers of values that a speculation attack might
|
||||
* otherwise want to exploit. The lower registers are likely clobbered
|
||||
* well before they could be put to use in a speculative execution
|
||||
* gadget.
|
||||
*/
|
||||
xorl %edx, %edx /* nospec dx */
|
||||
xorl %ecx, %ecx /* nospec cx */
|
||||
xorl %r8d, %r8d /* nospec r8 */
|
||||
xorl %r9d, %r9d /* nospec r9 */
|
||||
xorl %r10d, %r10d /* nospec r10 */
|
||||
xorl %r11d, %r11d /* nospec r11 */
|
||||
xorl %ebx, %ebx /* nospec rbx */
|
||||
xorl %ebp, %ebp /* nospec rbp */
|
||||
xorl %r12d, %r12d /* nospec r12 */
|
||||
xorl %r13d, %r13d /* nospec r13 */
|
||||
xorl %r14d, %r14d /* nospec r14 */
|
||||
xorl %r15d, %r15d /* nospec r15 */
|
||||
|
||||
.endm
|
||||
|
||||
.macro POP_REGS pop_rdi=1 skip_r11rcx=0
|
||||
|
|
Loading…
Reference in a new issue