Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull x86 pti updates from Thomas Gleixner:
"The speculative paranoia departement delivers a few more plugs for
possible (probably theoretical) spectre/mds leaks"

* 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/tls: Fix possible spectre-v1 in do_get_thread_area()
x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg()
x86/speculation/mds: Eliminate leaks by trace_hardirqs_on()

+12 -5
+2 -2
arch/x86/include/asm/mwait.h
··· 86 86 87 87 static inline void __sti_mwait(unsigned long eax, unsigned long ecx) 88 88 { 89 - mds_idle_clear_cpu_buffers(); 90 - 91 89 trace_hardirqs_on(); 90 + 91 + mds_idle_clear_cpu_buffers(); 92 92 /* "mwait %eax, %ecx;" */ 93 93 asm volatile("sti; .byte 0x0f, 0x01, 0xc9;" 94 94 :: "a" (eax), "c" (ecx));
+3 -1
arch/x86/kernel/ptrace.c
··· 25 25 #include <linux/rcupdate.h> 26 26 #include <linux/export.h> 27 27 #include <linux/context_tracking.h> 28 + #include <linux/nospec.h> 28 29 29 30 #include <linux/uaccess.h> 30 31 #include <asm/pgtable.h> ··· 636 635 unsigned long val = 0; 637 636 638 637 if (n < HBP_NUM) { 639 - struct perf_event *bp = thread->ptrace_bps[n]; 638 + int index = array_index_nospec(n, HBP_NUM); 639 + struct perf_event *bp = thread->ptrace_bps[index]; 640 640 641 641 if (bp) 642 642 val = bp->hw.info.address;
+7 -2
arch/x86/kernel/tls.c
··· 5 5 #include <linux/user.h> 6 6 #include <linux/regset.h> 7 7 #include <linux/syscalls.h> 8 + #include <linux/nospec.h> 8 9 9 10 #include <linux/uaccess.h> 10 11 #include <asm/desc.h> ··· 221 220 struct user_desc __user *u_info) 222 221 { 223 222 struct user_desc info; 223 + int index; 224 224 225 225 if (idx == -1 && get_user(idx, &u_info->entry_number)) 226 226 return -EFAULT; ··· 229 227 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) 230 228 return -EINVAL; 231 229 232 - fill_user_desc(&info, idx, 233 - &p->thread.tls_array[idx - GDT_ENTRY_TLS_MIN]); 230 + index = idx - GDT_ENTRY_TLS_MIN; 231 + index = array_index_nospec(index, 232 + GDT_ENTRY_TLS_MAX - GDT_ENTRY_TLS_MIN + 1); 233 + 234 + fill_user_desc(&info, idx, &p->thread.tls_array[index]); 234 235 235 236 if (copy_to_user(u_info, &info, sizeof(info))) 236 237 return -EFAULT;