History

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Ingo Molnar: "Various fixes: - Fix the PAT performance regression that downgraded write-combining device memory regions to uncached. - There's been a number of bugs in 32-bit double fault handling - hopefully all fixed now. - Fix an LDT crash - Fix an FPU over-optimization that broke with GCC9 code optimizations. - Misc cleanups" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/mm/pat: Fix off-by-one bugs in interval tree search x86/ioperm: Save an indentation level in tss_update_io_bitmap() x86/fpu: Don't cache access to fpu_fpregs_owner_ctx x86/entry/32: Remove unused 'restore_all_notrace' local label x86/ptrace: Document FSBASE and GSBASE ABI oddities x86/ptrace: Remove set_segment_reg() implementations for current x86/traps: die() instead of panicking on a double fault x86/doublefault/32: Rewrite the x86_32 #DF handler and unify with 64-bit x86/doublefault/32: Move #DF stack and TSS to cpu_entry_area x86/doublefault/32: Rename doublefault.c to doublefault_32.c x86/traps: Disentangle the 32-bit and 64-bit doublefault code lkdtm: Add a DOUBLE_FAULT crash type on x86 selftests/x86/single_step_syscall: Check SYSENTER directly x86/mm/32: Sync only to VMALLOC_END in vmalloc_sync_all()

Linus Torvalds committed 6 years ago

Commit e5b3fc12 parents b7fcf31 91298f123 files · +467 −171Browse files

Unified · Split

23 files
  1. arch/x86/Kconfig.debug +1 −1
  2. arch/x86/entry/entry_32.S +42 −1
  3. arch/x86/include/asm/cpu_entry_area.h +12 −0
  4. arch/x86/include/asm/doublefault.h +13 −0
  5. arch/x86/include/asm/fpu/internal.h +1 −1
  6. arch/x86/include/asm/pgtable_32_types.h +4 −3
  7. arch/x86/include/asm/processor.h +0 −2
  8. arch/x86/include/asm/traps.h +3 −0
  9. arch/x86/kernel/Makefile +3 −1
  10. arch/x86/kernel/cpu/common.c +2 −10
  11. arch/x86/kernel/doublefault.c +0 −86
  12. arch/x86/kernel/doublefault_32.c +136 −0
  13. arch/x86/kernel/dumpstack_32.c +30 −0
  14. arch/x86/kernel/process.c +26 −26
  15. arch/x86/kernel/ptrace.c +24 −12
  16. arch/x86/kernel/traps.c +20 −11
  17. arch/x86/mm/cpu_entry_area.c +13 −1
  18. arch/x86/mm/fault.c +1 −1
  19. arch/x86/mm/pat_interval.c +6 −6
  20. drivers/misc/lkdtm/bugs.c +39 −0
  21. drivers/misc/lkdtm/core.c +3 −0
  22. drivers/misc/lkdtm/lkdtm.h +3 −0
  23. tools/testing/selftests/x86/single_step_syscall.c +85 −9
arch/x86/Kconfig.debug+1−1
@@ -117,7 +117,7 @@ config DEBUG_WX · 116 unmodified lines
117117
118118 config DOUBLEFAULT
119119 default y
120− bool "Enable doublefault exception handler" if EXPERT
120+ bool "Enable doublefault exception handler" if EXPERT && X86_32
121121 ---help---
122122 This option allows trapping of rare doublefault exceptions that
123123 would otherwise cause a system to silently reboot. Disabling this
arch/x86/entry/entry_32.S+42−1
@@ -1090,7 +1090,6 @@ SYM_FUNC_START(entry_INT80_32) · 1089 unmodified lines
10901090 restore_all:
10911091 TRACE_IRQS_IRET
10921092 SWITCH_TO_ENTRY_STACK
1093−.Lrestore_all_notrace:
10941093 CHECK_AND_APPLY_ESPFIX
10951094 .Lrestore_nocheck:
10961095 /* Switch back to user CR3 */
@@ -1537,6 +1536,48 @@ SYM_CODE_START(debug) · 440 unmodified lines
15371536 jmp common_exception
15381537 SYM_CODE_END(debug)
15391538
1539+#ifdef CONFIG_DOUBLEFAULT
1540+SYM_CODE_START(double_fault)
1541+1:
1542+ /*
1543+ * This is a task gate handler, not an interrupt gate handler.
1544+ * The error code is on the stack, but the stack is otherwise
1545+ * empty. Interrupts are off. Our state is sane with the following
1546+ * exceptions:
1547+ *
1548+ * - CR0.TS is set. "TS" literally means "task switched".
1549+ * - EFLAGS.NT is set because we're a "nested task".
1550+ * - The doublefault TSS has back_link set and has been marked busy.
1551+ * - TR points to the doublefault TSS and the normal TSS is busy.
1552+ * - CR3 is the normal kernel PGD. This would be delightful, except
1553+ * that the CPU didn't bother to save the old CR3 anywhere. This
1554+ * would make it very awkward to return back to the context we came
1555+ * from.
1556+ *
1557+ * The rest of EFLAGS is sanitized for us, so we don't need to
1558+ * worry about AC or DF.
1559+ *
1560+ * Don't even bother popping the error code. It's always zero,
1561+ * and ignoring it makes us a bit more robust against buggy
1562+ * hypervisor task gate implementations.
1563+ *
1564+ * We will manually undo the task switch instead of doing a
1565+ * task-switching IRET.
1566+ */
1567+
1568+ clts /* clear CR0.TS */
1569+ pushl $X86_EFLAGS_FIXED
1570+ popfl /* clear EFLAGS.NT */
1571+
1572+ call doublefault_shim
1573+
1574+ /* We don't support returning, so we have no IRET here. */
1575+1:
1576+ hlt
1577+ jmp 1b
1578+SYM_CODE_END(double_fault)
1579+#endif
1580+
15401581 /*
15411582 * NMI is doubly nasty. It can happen on the first instruction of
15421583 * entry_SYSENTER_32 (just like #DB), but it can also interrupt the beginning
arch/x86/include/asm/cpu_entry_area.h+12−0
@@ -65,6 +65,13 @@ enum exception_stack_ordering { · 64 unmodified lines
6565
6666 #endif
6767
68+#ifdef CONFIG_X86_32
69+struct doublefault_stack {
70+ unsigned long stack[(PAGE_SIZE - sizeof(struct x86_hw_tss)) / sizeof(unsigned long)];
71+ struct x86_hw_tss tss;
72+} __aligned(PAGE_SIZE);
73+#endif
74+
6875 /*
6976 * cpu_entry_area is a percpu region that contains things needed by the CPU
7077 * and early entry/exit code. Real types aren't used for all fields here
@@ -86,6 +93,11 @@ struct cpu_entry_area { · 15 unmodified lines
8693 #endif
8794 struct entry_stack_page entry_stack_page;
8895
96+#ifdef CONFIG_X86_32
97+ char guard_doublefault_stack[PAGE_SIZE];
98+ struct doublefault_stack doublefault_stack;
99+#endif
100+
89101 /*
90102 * On x86_64, the TSS is mapped RO. On x86_32, it's mapped RW because
91103 * we need task switches to work, and task switches write to the TSS.
arch/x86/include/asm/doublefault.h+13−0
@@ -0,0 +1,13 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#ifndef _ASM_X86_DOUBLEFAULT_H
3+#define _ASM_X86_DOUBLEFAULT_H
4+
5+#if defined(CONFIG_X86_32) && defined(CONFIG_DOUBLEFAULT)
6+extern void doublefault_init_cpu_tss(void);
7+#else
8+static inline void doublefault_init_cpu_tss(void)
9+{
10+}
11+#endif
12+
13+#endif /* _ASM_X86_DOUBLEFAULT_H */
arch/x86/include/asm/fpu/internal.h+1−1
@@ -509,7 +509,7 @@ static inline void __fpu_invalidate_fpregs_state(struct fpu *fpu) · 508 unmodified lines
509509
510510 static inline int fpregs_state_valid(struct fpu *fpu, unsigned int cpu)
511511 {
512− return fpu == this_cpu_read_stable(fpu_fpregs_owner_ctx) && cpu == fpu->last_cpu;
512+ return fpu == this_cpu_read(fpu_fpregs_owner_ctx) && cpu == fpu->last_cpu;
513513 }
514514
515515 /*
arch/x86/include/asm/pgtable_32_types.h+4−3
@@ -41,10 +41,11 @@ extern bool __vmalloc_start_set; /* set once high_memory is set */ · 40 unmodified lines
4141 #endif
4242
4343 /*
44− * Define this here and validate with BUILD_BUG_ON() in pgtable_32.c
45− * to avoid include recursion hell
44+ * This is an upper bound on sizeof(struct cpu_entry_area) / PAGE_SIZE.
45+ * Define this here and validate with BUILD_BUG_ON() in cpu_entry_area.c
46+ * to avoid include recursion hell.
4647 */
47−#define CPU_ENTRY_AREA_PAGES (NR_CPUS * 41)
48+#define CPU_ENTRY_AREA_PAGES (NR_CPUS * 43)
4849
4950 /* The +1 is for the readonly IDT page: */
5051 #define CPU_ENTRY_AREA_BASE \
arch/x86/include/asm/processor.h+0−2
@@ -166,7 +166,6 @@ enum cpuid_regs_idx { · 165 unmodified lines
166166 extern struct cpuinfo_x86 boot_cpu_data;
167167 extern struct cpuinfo_x86 new_cpu_data;
168168
169−extern struct x86_hw_tss doublefault_tss;
170169 extern __u32 cpu_caps_cleared[NCAPINTS + NBUGINTS];
171170 extern __u32 cpu_caps_set[NCAPINTS + NBUGINTS];
172171
@@ -997,7 +996,6 @@ bool xen_set_default_idle(void); · 824 unmodified lines
997996 #endif
998997
999998 void stop_this_cpu(void *dummy);
1000−void df_debug(struct pt_regs *regs, long error_code);
1001999 void microcode_check(void);
10021000
10031001 enum l1tf_mitigations {
arch/x86/include/asm/traps.h+3−0
@@ -69,6 +69,9 @@ dotraplinkage void do_overflow(struct pt_regs *regs, long error_code); · 68 unmodified lines
6969 dotraplinkage void do_bounds(struct pt_regs *regs, long error_code);
7070 dotraplinkage void do_invalid_op(struct pt_regs *regs, long error_code);
7171 dotraplinkage void do_device_not_available(struct pt_regs *regs, long error_code);
72+#if defined(CONFIG_X86_64) || defined(CONFIG_DOUBLEFAULT)
73+dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code, unsigned long cr2);
74+#endif
7275 dotraplinkage void do_coprocessor_segment_overrun(struct pt_regs *regs, long error_code);
7376 dotraplinkage void do_invalid_TSS(struct pt_regs *regs, long error_code);
7477 dotraplinkage void do_segment_not_present(struct pt_regs *regs, long error_code);
arch/x86/kernel/Makefile+3−1
@@ -100,7 +100,9 @@ obj-$(CONFIG_KEXEC_FILE) += kexec-bzimage64.o · 99 unmodified lines
100100 obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
101101 obj-y += kprobes/
102102 obj-$(CONFIG_MODULES) += module.o
103−obj-$(CONFIG_DOUBLEFAULT) += doublefault.o
103+ifeq ($(CONFIG_X86_32),y)
104+obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o
105+endif
104106 obj-$(CONFIG_KGDB) += kgdb.o
105107 obj-$(CONFIG_VM86) += vm86_32.o
106108 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
arch/x86/kernel/cpu/common.c+2−10
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 #include <asm/stackprotector.h>
2525 #include <asm/perf_event.h>
2626 #include <asm/mmu_context.h>
27+#include <asm/doublefault.h>
2728 #include <asm/archrandom.h>
2829 #include <asm/hypervisor.h>
2930 #include <asm/processor.h>
@@ -1814,8 +1815,6 @@ static inline void tss_setup_ist(struct tss_struct *tss) · 1784 unmodified lines
18141815 tss->x86_tss.ist[IST_INDEX_MCE] = __this_cpu_ist_top_va(MCE);
18151816 }
18161817
1817−static inline void gdt_setup_doublefault_tss(int cpu) { }
1818−
18191818 #else /* CONFIG_X86_64 */
18201819
18211820 static inline void setup_getcpu(int cpu) { }
@@ -1827,13 +1826,6 @@ static inline void ucode_cpu_init(int cpu) · 5 unmodified lines
18271826
18281827 static inline void tss_setup_ist(struct tss_struct *tss) { }
18291828
1830−static inline void gdt_setup_doublefault_tss(int cpu)
1831−{
1832−#ifdef CONFIG_DOUBLEFAULT
1833− /* Set up the doublefault TSS pointer in the GDT */
1834− __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
1835−#endif
1836−}
18371829 #endif /* !CONFIG_X86_64 */
18381830
18391831 static inline void tss_setup_io_bitmap(struct tss_struct *tss)
@@ -1923,7 +1915,7 @@ void cpu_init(void) · 83 unmodified lines
19231915 clear_all_debug_regs();
19241916 dbg_restore_debug_regs();
19251917
1926− gdt_setup_doublefault_tss(cpu);
1918+ doublefault_init_cpu_tss();
19271919
19281920 fpu__init_cpu();
19291921
arch/x86/kernel/doublefault.c+0−86
@@ -1,86 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0
2−#include <linux/mm.h>
3−#include <linux/sched.h>
4−#include <linux/sched/debug.h>
5−#include <linux/init_task.h>
6−#include <linux/fs.h>
7−
8−#include <linux/uaccess.h>
9−#include <asm/pgtable.h>
10−#include <asm/processor.h>
11−#include <asm/desc.h>
12−
13−#ifdef CONFIG_X86_32
14−
15−#define DOUBLEFAULT_STACKSIZE (1024)
16−static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
17−#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
18−
19−#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
20−
21−static void doublefault_fn(void)
22−{
23− struct desc_ptr gdt_desc = {0, 0};
24− unsigned long gdt, tss;
25−
26− native_store_gdt(&gdt_desc);
27− gdt = gdt_desc.address;
28−
29− printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
30−
31− if (ptr_ok(gdt)) {
32− gdt += GDT_ENTRY_TSS << 3;
33− tss = get_desc_base((struct desc_struct *)gdt);
34− printk(KERN_EMERG "double fault, tss at %08lx\n", tss);
35−
36− if (ptr_ok(tss)) {
37− struct x86_hw_tss *t = (struct x86_hw_tss *)tss;
38−
39− printk(KERN_EMERG "eip = %08lx, esp = %08lx\n",
40− t->ip, t->sp);
41−
42− printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
43− t->ax, t->bx, t->cx, t->dx);
44− printk(KERN_EMERG "esi = %08lx, edi = %08lx\n",
45− t->si, t->di);
46− }
47− }
48−
49− for (;;)
50− cpu_relax();
51−}
52−
53−struct x86_hw_tss doublefault_tss __cacheline_aligned = {
54− .sp0 = STACK_START,
55− .ss0 = __KERNEL_DS,
56− .ldt = 0,
57− .io_bitmap_base = IO_BITMAP_OFFSET_INVALID,
58−
59− .ip = (unsigned long) doublefault_fn,
60− /* 0x2 bit is always set */
61− .flags = X86_EFLAGS_SF | 0x2,
62− .sp = STACK_START,
63− .es = __USER_DS,
64− .cs = __KERNEL_CS,
65− .ss = __KERNEL_DS,
66− .ds = __USER_DS,
67− .fs = __KERNEL_PERCPU,
68−#ifndef CONFIG_X86_32_LAZY_GS
69− .gs = __KERNEL_STACK_CANARY,
70−#endif
71−
72− .__cr3 = __pa_nodebug(swapper_pg_dir),
73−};
74−
75−/* dummy for do_double_fault() call */
76−void df_debug(struct pt_regs *regs, long error_code) {}
77−
78−#else /* !CONFIG_X86_32 */
79−
80−void df_debug(struct pt_regs *regs, long error_code)
81−{
82− pr_emerg("PANIC: double fault, error_code: 0x%lx\n", error_code);
83− show_regs(regs);
84− panic("Machine halted.");
85−}
86−#endif
arch/x86/kernel/doublefault_32.c+136−0
@@ -0,0 +1,136 @@
1+// SPDX-License-Identifier: GPL-2.0
2+#include <linux/mm.h>
3+#include <linux/sched.h>
4+#include <linux/sched/debug.h>
5+#include <linux/init_task.h>
6+#include <linux/fs.h>
7+
8+#include <linux/uaccess.h>
9+#include <asm/pgtable.h>
10+#include <asm/processor.h>
11+#include <asm/desc.h>
12+#include <asm/traps.h>
13+
14+extern void double_fault(void);
15+#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
16+
17+#define TSS(x) this_cpu_read(cpu_tss_rw.x86_tss.x)
18+
19+static void set_df_gdt_entry(unsigned int cpu);
20+
21+/*
22+ * Called by double_fault with CR0.TS and EFLAGS.NT cleared. The CPU thinks
23+ * we're running the doublefault task. Cannot return.
24+ */
25+asmlinkage notrace void __noreturn doublefault_shim(void)
26+{
27+ unsigned long cr2;
28+ struct pt_regs regs;
29+
30+ BUILD_BUG_ON(sizeof(struct doublefault_stack) != PAGE_SIZE);
31+
32+ cr2 = native_read_cr2();
33+
34+ /* Reset back to the normal kernel task. */
35+ force_reload_TR();
36+ set_df_gdt_entry(smp_processor_id());
37+
38+ trace_hardirqs_off();
39+
40+ /*
41+ * Fill in pt_regs. A downside of doing this in C is that the unwinder
42+ * won't see it (no ENCODE_FRAME_POINTER), so a nested stack dump
43+ * won't successfully unwind to the source of the double fault.
44+ * The main dump from do_double_fault() is fine, though, since it
45+ * uses these regs directly.
46+ *
47+ * If anyone ever cares, this could be moved to asm.
48+ */
49+ regs.ss = TSS(ss);
50+ regs.__ssh = 0;
51+ regs.sp = TSS(sp);
52+ regs.flags = TSS(flags);
53+ regs.cs = TSS(cs);
54+ /* We won't go through the entry asm, so we can leave __csh as 0. */
55+ regs.__csh = 0;
56+ regs.ip = TSS(ip);
57+ regs.orig_ax = 0;
58+ regs.gs = TSS(gs);
59+ regs.__gsh = 0;
60+ regs.fs = TSS(fs);
61+ regs.__fsh = 0;
62+ regs.es = TSS(es);
63+ regs.__esh = 0;
64+ regs.ds = TSS(ds);
65+ regs.__dsh = 0;
66+ regs.ax = TSS(ax);
67+ regs.bp = TSS(bp);
68+ regs.di = TSS(di);
69+ regs.si = TSS(si);
70+ regs.dx = TSS(dx);
71+ regs.cx = TSS(cx);
72+ regs.bx = TSS(bx);
73+
74+ do_double_fault(&regs, 0, cr2);
75+
76+ /*
77+ * x86_32 does not save the original CR3 anywhere on a task switch.
78+ * This means that, even if we wanted to return, we would need to find
79+ * some way to reconstruct CR3. We could make a credible guess based
80+ * on cpu_tlbstate, but that would be racy and would not account for
81+ * PTI.
82+ *
83+ * Instead, don't bother. We can return through
84+ * rewind_stack_do_exit() instead.
85+ */
86+ panic("cannot return from double fault\n");
87+}
88+NOKPROBE_SYMBOL(doublefault_shim);
89+
90+DEFINE_PER_CPU_PAGE_ALIGNED(struct doublefault_stack, doublefault_stack) = {
91+ .tss = {
92+ /*
93+ * No sp0 or ss0 -- we never run CPL != 0 with this TSS
94+ * active. sp is filled in later.
95+ */
96+ .ldt = 0,
97+ .io_bitmap_base = IO_BITMAP_OFFSET_INVALID,
98+
99+ .ip = (unsigned long) double_fault,
100+ .flags = X86_EFLAGS_FIXED,
101+ .es = __USER_DS,
102+ .cs = __KERNEL_CS,
103+ .ss = __KERNEL_DS,
104+ .ds = __USER_DS,
105+ .fs = __KERNEL_PERCPU,
106+#ifndef CONFIG_X86_32_LAZY_GS
107+ .gs = __KERNEL_STACK_CANARY,
108+#endif
109+
110+ .__cr3 = __pa_nodebug(swapper_pg_dir),
111+ },
112+};
113+
114+static void set_df_gdt_entry(unsigned int cpu)
115+{
116+ /* Set up doublefault TSS pointer in the GDT */
117+ __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS,
118+ &get_cpu_entry_area(cpu)->doublefault_stack.tss);
119+
120+}
121+
122+void doublefault_init_cpu_tss(void)
123+{
124+ unsigned int cpu = smp_processor_id();
125+ struct cpu_entry_area *cea = get_cpu_entry_area(cpu);
126+
127+ /*
128+ * The linker isn't smart enough to initialize percpu variables that
129+ * point to other places in percpu space.
130+ */
131+ this_cpu_write(doublefault_stack.tss.sp,
132+ (unsigned long)&cea->doublefault_stack.stack +
133+ sizeof(doublefault_stack.stack));
134+
135+ set_df_gdt_entry(cpu);
136+}
arch/x86/kernel/dumpstack_32.c+30−0
@@ -29,6 +29,9 @@ const char *stack_type_name(enum stack_type type) · 28 unmodified lines
2929 if (type == STACK_TYPE_ENTRY)
3030 return "ENTRY_TRAMPOLINE";
3131
32+ if (type == STACK_TYPE_EXCEPTION)
33+ return "#DF";
34+
3235 return NULL;
3336 }
3437
@@ -82,6 +85,30 @@ static bool in_softirq_stack(unsigned long *stack, struct stack_info *info) · 47 unmodified lines
8285 return true;
8386 }
8487
88+static bool in_doublefault_stack(unsigned long *stack, struct stack_info *info)
89+{
90+#ifdef CONFIG_DOUBLEFAULT
91+ struct cpu_entry_area *cea = get_cpu_entry_area(raw_smp_processor_id());
92+ struct doublefault_stack *ss = &cea->doublefault_stack;
93+
94+ void *begin = ss->stack;
95+ void *end = begin + sizeof(ss->stack);
96+
97+ if ((void *)stack < begin || (void *)stack >= end)
98+ return false;
99+
100+ info->type = STACK_TYPE_EXCEPTION;
101+ info->begin = begin;
102+ info->end = end;
103+ info->next_sp = (unsigned long *)this_cpu_read(cpu_tss_rw.x86_tss.sp);
104+
105+ return true;
106+#else
107+ return false;
108+#endif
109+}
110+
111+
85112 int get_stack_info(unsigned long *stack, struct task_struct *task,
86113 struct stack_info *info, unsigned long *visit_mask)
87114 {
@@ -105,6 +132,9 @@ int get_stack_info(unsigned long *stack, struct task_struct *task, · 17 unmodified lines
105132 if (in_softirq_stack(stack, info))
106133 goto recursion_check;
107134
135+ if (in_doublefault_stack(stack, info))
136+ goto recursion_check;
137+
108138 goto unknown;
109139
110140 recursion_check:
arch/x86/kernel/process.c+26−26
@@ -377,37 +377,37 @@ static void tss_copy_io_bitmap(struct tss_struct *tss, struct io_bitmap *iobm) · 376 unmodified lines
377377 void tss_update_io_bitmap(void)
378378 {
379379 struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw);
380+ struct thread_struct *t = &current->thread;
380381 u16 *base = &tss->x86_tss.io_bitmap_base;
381382
382− if (test_thread_flag(TIF_IO_BITMAP)) {
383− struct thread_struct *t = &current->thread;
384−
385− if (IS_ENABLED(CONFIG_X86_IOPL_IOPERM) && t->iopl_emul == 3) {
386− *base = IO_BITMAP_OFFSET_VALID_ALL;
387− } else {
388− struct io_bitmap *iobm = t->io_bitmap;
389− /*
390− * Only copy bitmap data when the sequence number
391− * differs. The update time is accounted to the
392− * incoming task.
393− */
394− if (tss->io_bitmap.prev_sequence != iobm->sequence)
395− tss_copy_io_bitmap(tss, iobm);
396−
397− /* Enable the bitmap */
398− *base = IO_BITMAP_OFFSET_VALID_MAP;
399− }
383+ if (!test_thread_flag(TIF_IO_BITMAP)) {
384+ tss_invalidate_io_bitmap(tss);
385+ return;
386+ }
387+
388+ if (IS_ENABLED(CONFIG_X86_IOPL_IOPERM) && t->iopl_emul == 3) {
389+ *base = IO_BITMAP_OFFSET_VALID_ALL;
390+ } else {
391+ struct io_bitmap *iobm = t->io_bitmap;
392+
400393 /*
401− * Make sure that the TSS limit is covering the io bitmap.
402− * It might have been cut down by a VMEXIT to 0x67 which
403− * would cause a subsequent I/O access from user space to
404− * trigger a #GP because tbe bitmap is outside the TSS
405− * limit.
394+ * Only copy bitmap data when the sequence number differs. The
395+ * update time is accounted to the incoming task.
406396 */
407− refresh_tss_limit();
408− } else {
409− tss_invalidate_io_bitmap(tss);
397+ if (tss->io_bitmap.prev_sequence != iobm->sequence)
398+ tss_copy_io_bitmap(tss, iobm);
399+
400+ /* Enable the bitmap */
401+ *base = IO_BITMAP_OFFSET_VALID_MAP;
410402 }
403+
404+ /*
405+ * Make sure that the TSS limit is covering the IO bitmap. It might have
406+ * been cut down by a VMEXIT to 0x67 which would cause a subsequent I/O
407+ * access from user space to trigger a #GP because tbe bitmap is outside
408+ * the TSS limit.
409+ */
410+ refresh_tss_limit();
411411 }
412412 #else /* CONFIG_X86_IOPL_IOPERM */
413413 static inline void switch_to_bitmap(unsigned long tifp) { }
arch/x86/kernel/ptrace.c+24−12
@@ -182,6 +182,9 @@ static u16 get_segment_reg(struct task_struct *task, unsigned long offset) · 181 unmodified lines
182182 static int set_segment_reg(struct task_struct *task,
183183 unsigned long offset, u16 value)
184184 {
185+ if (WARN_ON_ONCE(task == current))
186+ return -EIO;
187+
185188 /*
186189 * The value argument was already truncated to 16 bits.
187190 */
@@ -209,10 +212,7 @@ static int set_segment_reg(struct task_struct *task, · 21 unmodified lines
209212 break;
210213
211214 case offsetof(struct user_regs_struct, gs):
212− if (task == current)
213− set_user_gs(task_pt_regs(task), value);
214− else
215− task_user_gs(task) = value;
215+ task_user_gs(task) = value;
216216 }
217217
218218 return 0;
@@ -272,32 +272,41 @@ static u16 get_segment_reg(struct task_struct *task, unsigned long offset) · 53 unmodified lines
272272 static int set_segment_reg(struct task_struct *task,
273273 unsigned long offset, u16 value)
274274 {
275+ if (WARN_ON_ONCE(task == current))
276+ return -EIO;
277+
275278 /*
276279 * The value argument was already truncated to 16 bits.
277280 */
278281 if (invalid_selector(value))
279282 return -EIO;
280283
284+ /*
285+ * This function has some ABI oddities.
286+ *
287+ * A 32-bit ptracer probably expects that writing FS or GS will change
288+ * FSBASE or GSBASE respectively. In the absence of FSGSBASE support,
289+ * this code indeed has that effect. When FSGSBASE is added, this
290+ * will require a special case.
291+ *
292+ * For existing 64-bit ptracers, writing FS or GS *also* currently
293+ * changes the base if the selector is nonzero the next time the task
294+ * is run. This behavior may not be needed, and trying to preserve it
295+ * when FSGSBASE is added would be complicated at best.
296+ */
297+
281298 switch (offset) {
282299 case offsetof(struct user_regs_struct,fs):
283300 task->thread.fsindex = value;
284− if (task == current)
285− loadsegment(fs, task->thread.fsindex);
286301 break;
287302 case offsetof(struct user_regs_struct,gs):
288303 task->thread.gsindex = value;
289− if (task == current)
290− load_gs_index(task->thread.gsindex);
291304 break;
292305 case offsetof(struct user_regs_struct,ds):
293306 task->thread.ds = value;
294− if (task == current)
295− loadsegment(ds, task->thread.ds);
296307 break;
297308 case offsetof(struct user_regs_struct,es):
298309 task->thread.es = value;
299− if (task == current)
300− loadsegment(es, task->thread.es);
301310 break;
302311
303312 /*
@@ -375,6 +384,9 @@ static int putreg(struct task_struct *child, · 71 unmodified lines
375384 * When changing the FS base, use do_arch_prctl_64()
376385 * to set the index to zero and to set the base
377386 * as requested.
387+ *
388+ * NB: This behavior is nonsensical and likely needs to
389+ * change when FSGSBASE support is added.
378390 */
379391 if (child->thread.fsbase != value)
380392 return do_arch_prctl_64(child, ARCH_SET_FS, value);
arch/x86/kernel/traps.c+20−11
@@ -306,8 +306,23 @@ __visible void __noreturn handle_stack_overflow(const char *message, · 305 unmodified lines
306306 }
307307 #endif
308308
309−#ifdef CONFIG_X86_64
310−/* Runs on IST stack */
309+#if defined(CONFIG_X86_64) || defined(CONFIG_DOUBLEFAULT)
310+/*
311+ * Runs on an IST stack for x86_64 and on a special task stack for x86_32.
312+ *
313+ * On x86_64, this is more or less a normal kernel entry. Notwithstanding the
314+ * SDM's warnings about double faults being unrecoverable, returning works as
315+ * expected. Presumably what the SDM actually means is that the CPU may get
316+ * the register state wrong on entry, so returning could be a bad idea.
317+ *
318+ * Various CPU engineers have promised that double faults due to an IRET fault
319+ * while the stack is read-only are, in fact, recoverable.
320+ *
321+ * On x86_32, this is entered through a task gate, and regs are synthesized
322+ * from the TSS. Returning is, in principle, okay, but changes to regs will
323+ * be lost. If, for some reason, we need to return to a context with modified
324+ * regs, the shim code could be adjusted to synchronize the registers.
325+ */
311326 dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code, unsigned long cr2)
312327 {
313328 static const char str[] = "double fault";
@@ -411,15 +426,9 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code, unsign · 97 unmodified lines
411426 handle_stack_overflow("kernel stack overflow (double-fault)", regs, cr2);
412427 #endif
413428
414−#ifdef CONFIG_DOUBLEFAULT
415− df_debug(regs, error_code);
416−#endif
417− /*
418− * This is always a kernel trap and never fixable (and thus must
419− * never return).
420− */
421− for (;;)
422− die(str, regs, error_code);
429+ pr_emerg("PANIC: double fault, error_code: 0x%lx\n", error_code);
430+ die("double fault", regs, error_code);
431+ panic("Machine halted.");
423432 }
424433 #endif
425434
arch/x86/mm/cpu_entry_area.c+13−1
@@ -17,6 +17,10 @@ static DEFINE_PER_CPU_PAGE_ALIGNED(struct exception_stacks, exception_stacks); · 16 unmodified lines
1717 DEFINE_PER_CPU(struct cea_exception_stacks*, cea_exception_stacks);
1818 #endif
1919
20+#if defined(CONFIG_X86_32) && defined(CONFIG_DOUBLEFAULT)
21+DECLARE_PER_CPU_PAGE_ALIGNED(struct doublefault_stack, doublefault_stack);
22+#endif
23+
2024 struct cpu_entry_area *get_cpu_entry_area(int cpu)
2125 {
2226 unsigned long va = CPU_ENTRY_AREA_PER_CPU + cpu * CPU_ENTRY_AREA_SIZE;
@@ -108,7 +112,15 @@ static void __init percpu_setup_exception_stacks(unsigned int cpu) · 85 unmodified lines
108112 cea_map_stack(MCE);
109113 }
110114 #else
111−static inline void percpu_setup_exception_stacks(unsigned int cpu) {}
115+static inline void percpu_setup_exception_stacks(unsigned int cpu)
116+{
117+#ifdef CONFIG_DOUBLEFAULT
118+ struct cpu_entry_area *cea = get_cpu_entry_area(cpu);
119+
120+ cea_map_percpu_pages(&cea->doublefault_stack,
121+ &per_cpu(doublefault_stack, cpu), 1, PAGE_KERNEL);
122+#endif
123+}
112124 #endif
113125
114126 /* Setup the fixmap mappings only once per-processor */
arch/x86/mm/fault.c+1−1
@@ -197,7 +197,7 @@ void vmalloc_sync_all(void) · 196 unmodified lines
197197 return;
198198
199199 for (address = VMALLOC_START & PMD_MASK;
200− address >= TASK_SIZE_MAX && address < FIXADDR_TOP;
200+ address >= TASK_SIZE_MAX && address < VMALLOC_END;
201201 address += PMD_SIZE) {
202202 struct page *page;
203203
arch/x86/mm/pat_interval.c+6−6
@@ -56,7 +56,7 @@ static struct memtype *memtype_match(u64 start, u64 end, int match_type) · 55 unmodified lines
5656 {
5757 struct memtype *match;
5858
59− match = memtype_interval_iter_first(&memtype_rbroot, start, end);
59+ match = memtype_interval_iter_first(&memtype_rbroot, start, end-1);
6060 while (match != NULL && match->start < end) {
6161 if ((match_type == MEMTYPE_EXACT_MATCH) &&
6262 (match->start == start) && (match->end == end))
@@ -66,7 +66,7 @@ static struct memtype *memtype_match(u64 start, u64 end, int match_type) · 3 unmodified lines
6666 (match->start < start) && (match->end == end))
6767 return match;
6868
69− match = memtype_interval_iter_next(match, start, end);
69+ match = memtype_interval_iter_next(match, start, end-1);
7070 }
7171
7272 return NULL; /* Returns NULL if there is no match */
@@ -79,7 +79,7 @@ static int memtype_check_conflict(u64 start, u64 end, · 6 unmodified lines
7979 struct memtype *match;
8080 enum page_cache_mode found_type = reqtype;
8181
82− match = memtype_interval_iter_first(&memtype_rbroot, start, end);
82+ match = memtype_interval_iter_first(&memtype_rbroot, start, end-1);
8383 if (match == NULL)
8484 goto success;
8585
@@ -89,12 +89,12 @@ static int memtype_check_conflict(u64 start, u64 end, · 3 unmodified lines
8989 dprintk("Overlap at 0x%Lx-0x%Lx\n", match->start, match->end);
9090 found_type = match->type;
9191
92− match = memtype_interval_iter_next(match, start, end);
92+ match = memtype_interval_iter_next(match, start, end-1);
9393 while (match) {
9494 if (match->type != found_type)
9595 goto failure;
9696
97− match = memtype_interval_iter_next(match, start, end);
97+ match = memtype_interval_iter_next(match, start, end-1);
9898 }
9999 success:
100100 if (newtype)
@@ -160,7 +160,7 @@ struct memtype *memtype_erase(u64 start, u64 end) · 59 unmodified lines
160160 struct memtype *memtype_lookup(u64 addr)
161161 {
162162 return memtype_interval_iter_first(&memtype_rbroot, addr,
163− addr + PAGE_SIZE);
163+ addr + PAGE_SIZE-1);
164164 }
165165
166166 #if defined(CONFIG_DEBUG_FS)
drivers/misc/lkdtm/bugs.c+39−0
@@ -12,6 +12,10 @@ · 11 unmodified lines
1212 #include <linux/sched/task_stack.h>
1313 #include <linux/uaccess.h>
1414
15+#ifdef CONFIG_X86_32
16+#include <asm/desc.h>
17+#endif
18+
1519 struct lkdtm_list {
1620 struct list_head node;
1721 };
@@ -337,3 +341,38 @@ void lkdtm_UNSET_SMEP(void) · 319 unmodified lines
337341 pr_err("FAIL: this test is x86_64-only\n");
338342 #endif
339343 }
344+
345+#ifdef CONFIG_X86_32
346+void lkdtm_DOUBLE_FAULT(void)
347+{
348+ /*
349+ * Trigger #DF by setting the stack limit to zero. This clobbers
350+ * a GDT TLS slot, which is okay because the current task will die
351+ * anyway due to the double fault.
352+ */
353+ struct desc_struct d = {
354+ .type = 3, /* expand-up, writable, accessed data */
355+ .p = 1, /* present */
356+ .d = 1, /* 32-bit */
357+ .g = 0, /* limit in bytes */
358+ .s = 1, /* not system */
359+ };
360+
361+ local_irq_disable();
362+ write_gdt_entry(get_cpu_gdt_rw(smp_processor_id()),
363+ GDT_ENTRY_TLS_MIN, &d, DESCTYPE_S);
364+
365+ /*
366+ * Put our zero-limit segment in SS and then trigger a fault. The
367+ * 4-byte access to (%esp) will fault with #SS, and the attempt to
368+ * deliver the fault will recursively cause #SS and result in #DF.
369+ * This whole process happens while NMIs and MCEs are blocked by the
370+ * MOV SS window. This is nice because an NMI with an invalid SS
371+ * would also double-fault, resulting in the NMI or MCE being lost.
372+ */
373+ asm volatile ("movw %0, %%ss; addl $0, (%%esp)" ::
374+ "r" ((unsigned short)(GDT_ENTRY_TLS_MIN << 3)));
375+
376+ panic("tried to double fault but didn't die\n");
377+}
378+#endif
drivers/misc/lkdtm/core.c+3−0
@@ -171,6 +171,9 @@ static const struct crashtype crashtypes[] = { · 170 unmodified lines
171171 CRASHTYPE(USERCOPY_KERNEL_DS),
172172 CRASHTYPE(STACKLEAK_ERASING),
173173 CRASHTYPE(CFI_FORWARD_PROTO),
174+#ifdef CONFIG_X86_32
175+ CRASHTYPE(DOUBLE_FAULT),
176+#endif
174177 };
175178
176179
drivers/misc/lkdtm/lkdtm.h+3−0
@@ -28,6 +28,9 @@ void lkdtm_CORRUPT_USER_DS(void); · 27 unmodified lines
2828 void lkdtm_STACK_GUARD_PAGE_LEADING(void);
2929 void lkdtm_STACK_GUARD_PAGE_TRAILING(void);
3030 void lkdtm_UNSET_SMEP(void);
31+#ifdef CONFIG_X86_32
32+void lkdtm_DOUBLE_FAULT(void);
33+#endif
3134
3235 /* lkdtm_heap.c */
3336 void __init lkdtm_heap_init(void);
tools/testing/selftests/x86/single_step_syscall.c+85−9
@@ -43,7 +43,19 @@ static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), · 42 unmodified lines
4343 err(1, "sigaction");
4444 }
4545
46−static volatile sig_atomic_t sig_traps;
46+static void clearhandler(int sig)
47+{
48+ struct sigaction sa;
49+ memset(&sa, 0, sizeof(sa));
50+ sa.sa_handler = SIG_DFL;
51+ sigemptyset(&sa.sa_mask);
52+ if (sigaction(sig, &sa, 0))
53+ err(1, "sigaction");
54+}
55+
56+static volatile sig_atomic_t sig_traps, sig_eflags;
57+sigjmp_buf jmpbuf;
58+static unsigned char altstack_data[SIGSTKSZ];
4759
4860 #ifdef __x86_64__
4961 # define REG_IP REG_RIP
@@ -90,6 +102,25 @@ static void sigtrap(int sig, siginfo_t *info, void *ctx_void) · 40 unmodified lines
90102 }
91103 }
92104
105+static char const * const signames[] = {
106+ [SIGSEGV] = "SIGSEGV",
107+ [SIGBUS] = "SIBGUS",
108+ [SIGTRAP] = "SIGTRAP",
109+ [SIGILL] = "SIGILL",
110+};
111+
112+static void print_and_longjmp(int sig, siginfo_t *si, void *ctx_void)
113+{
114+ ucontext_t *ctx = ctx_void;
115+
116+ printf("\tGot %s with RIP=%lx, TF=%ld\n", signames[sig],
117+ (unsigned long)ctx->uc_mcontext.gregs[REG_IP],
118+ (unsigned long)ctx->uc_mcontext.gregs[REG_EFL] & X86_EFLAGS_TF);
119+
120+ sig_eflags = (unsigned long)ctx->uc_mcontext.gregs[REG_EFL];
121+ siglongjmp(jmpbuf, 1);
122+}
123+
93124 static void check_result(void)
94125 {
95126 unsigned long new_eflags = get_eflags();
@@ -109,6 +140,22 @@ static void check_result(void) · 13 unmodified lines
109140 sig_traps = 0;
110141 }
111142
143+static void fast_syscall_no_tf(void)
144+{
145+ sig_traps = 0;
146+ printf("[RUN]\tFast syscall with TF cleared\n");
147+ fflush(stdout); /* Force a syscall */
148+ if (get_eflags() & X86_EFLAGS_TF) {
149+ printf("[FAIL]\tTF is now set\n");
150+ exit(1);
151+ }
152+ if (sig_traps) {
153+ printf("[FAIL]\tGot SIGTRAP\n");
154+ exit(1);
155+ }
156+ printf("[OK]\tNothing unexpected happened\n");
157+}
158+
112159 int main()
113160 {
114161 #ifdef CAN_BUILD_32
@@ -163,17 +210,46 @@ int main() · 48 unmodified lines
163210 check_result();
164211
165212 /* Now make sure that another fast syscall doesn't set TF again. */
166− printf("[RUN]\tFast syscall with TF cleared\n");
167− fflush(stdout); /* Force a syscall */
168− if (get_eflags() & X86_EFLAGS_TF) {
169− printf("[FAIL]\tTF is now set\n");
170− exit(1);
213+ fast_syscall_no_tf();
214+
215+ /*
216+ * And do a forced SYSENTER to make sure that this works even if
217+ * fast syscalls don't use SYSENTER.
218+ *
219+ * Invoking SYSENTER directly breaks all the rules. Just handle
220+ * the SIGSEGV.
221+ */
222+ if (sigsetjmp(jmpbuf, 1) == 0) {
223+ unsigned long nr = SYS_getpid;
224+ printf("[RUN]\tSet TF and check SYSENTER\n");
225+ stack_t stack = {
226+ .ss_sp = altstack_data,
227+ .ss_size = SIGSTKSZ,
228+ };
229+ if (sigaltstack(&stack, NULL) != 0)
230+ err(1, "sigaltstack");
231+ sethandler(SIGSEGV, print_and_longjmp,
232+ SA_RESETHAND | SA_ONSTACK);
233+ sethandler(SIGILL, print_and_longjmp, SA_RESETHAND);
234+ set_eflags(get_eflags() | X86_EFLAGS_TF);
235+ /* Clear EBP first to make sure we segfault cleanly. */
236+ asm volatile ("xorl %%ebp, %%ebp; SYSENTER" : "+a" (nr) :: "flags", "rcx"
237+#ifdef __x86_64__
238+ , "r11"
239+#endif
240+ );
241+
242+ /* We're unreachable here. SYSENTER forgets RIP. */
171243 }
172− if (sig_traps) {
173− printf("[FAIL]\tGot SIGTRAP\n");
244+ clearhandler(SIGSEGV);
245+ clearhandler(SIGILL);
246+ if (!(sig_eflags & X86_EFLAGS_TF)) {
247+ printf("[FAIL]\tTF was cleared\n");
174248 exit(1);
175249 }
176− printf("[OK]\tNothing unexpected happened\n");
250+
251+ /* Now make sure that another fast syscall doesn't set TF again. */
252+ fast_syscall_no_tf();
177253
178254 return 0;
179255 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t