From 040e1457c109185a5420e24203cad8e92f3caaca Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Tue, 11 Apr 2017 15:39:08 +0100 Subject: [PATCH] x86/traps: Poison unused stack pointers in the TSS This is for additional defence-in-depth following LDT/GDT/IDT corruption. It causes attempted control transfers to ring 1 or 2 (via a call gate), or attempts to use IST 3 through 7 to yield #SS, rather than executing with a stack starting at the top of virtual address space. Express the TSS setup in terms of structure assignment, which should be less fragile if the IST indexes need to change, and has the useful side effect of zeroing the reserved fields. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich Release-acked-by: Julien Grall --- xen/arch/x86/cpu/common.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 6c27008d7b..2fdc2f98aa 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -636,14 +636,29 @@ void load_system_tables(void) .limit = (IDT_ENTRIES * sizeof(idt_entry_t)) - 1, }; - /* Main stack for interrupts/exceptions. */ - tss->rsp0 = stack_bottom; - tss->bitmap = IOBMP_INVALID_OFFSET; - - /* MCE, NMI and Double Fault handlers get their own stacks. */ - tss->ist[IST_MCE - 1] = stack_top + IST_MCE * PAGE_SIZE; - tss->ist[IST_DF - 1] = stack_top + IST_DF * PAGE_SIZE; - tss->ist[IST_NMI - 1] = stack_top + IST_NMI * PAGE_SIZE; + *tss = (struct tss_struct){ + /* Main stack for interrupts/exceptions. */ + .rsp0 = stack_bottom, + + /* Ring 1 and 2 stacks poisoned. */ + .rsp1 = 0x8600111111111111ul, + .rsp2 = 0x8600111111111111ul, + + /* + * MCE, NMI and Double Fault handlers get their own stacks. + * All others poisoned. + */ + .ist = { + [IST_MCE - 1] = stack_top + IST_MCE * PAGE_SIZE, + [IST_DF - 1] = stack_top + IST_DF * PAGE_SIZE, + [IST_NMI - 1] = stack_top + IST_NMI * PAGE_SIZE, + + [IST_MAX ... ARRAY_SIZE(tss->ist) - 1] = + 0x8600111111111111ul, + }, + + .bitmap = IOBMP_INVALID_OFFSET, + }; _set_tssldt_desc( gdt + TSS_ENTRY, -- 2.39.5