]> xenbits.xensource.com Git - xen.git/commitdiff
x86/traps: Poison unused stack pointers in the TSS
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 11 Apr 2017 14:39:08 +0000 (15:39 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 5 May 2017 08:54:28 +0000 (09:54 +0100)
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 <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Julien Grall <julien.grall@arm.com>
xen/arch/x86/cpu/common.c

index 6c27008d7b7764c9955f6c40973fec542b6568bf..2fdc2f98aabe696e206bf1bfe342cac936be8257 100644 (file)
@@ -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,