linux/arch/x86/kernel
Kees Cook 873d50d58f x86/asm: Pin sensitive CR4 bits
Several recent exploits have used direct calls to the native_write_cr4()
function to disable SMEP and SMAP before then continuing their exploits
using userspace memory access.

Direct calls of this form can be mitigate by pinning bits of CR4 so that
they cannot be changed through a common function. This is not intended to
be a general ROP protection (which would require CFI to defend against
properly), but rather a way to avoid trivial direct function calling (or
CFI bypasses via a matching function prototype) as seen in:

https://googleprojectzero.blogspot.com/2017/05/exploiting-linux-kernel-via-packet.html
(https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-7308)

The goals of this change:

 - Pin specific bits (SMEP, SMAP, and UMIP) when writing CR4.

 - Avoid setting the bits too early (they must become pinned only after
   CPU feature detection and selection has finished).

 - Pinning mask needs to be read-only during normal runtime.

 - Pinning needs to be checked after write to validate the cr4 state

Using __ro_after_init on the mask is done so it can't be first disabled
with a malicious write.

Since these bits are global state (once established by the boot CPU and
kernel boot parameters), they are safe to write to secondary CPUs before
those CPUs have finished feature detection. As such, the bits are set at
the first cr4 write, so that cr4 write bugs can be detected (instead of
silently papered over). This uses a few bytes less storage of a location we
don't have: read-only per-CPU data.

A check is performed after the register write because an attack could just
skip directly to the register write. Such a direct jump is possible because
of how this function may be built by the compiler (especially due to the
removal of frame pointers) where it doesn't add a stack frame (function
exit may only be a retq without pops) which is sufficient for trivial
exploitation like in the timer overwrites mentioned above).

The asm argument constraints gain the "+" modifier to convince the compiler
that it shouldn't make ordering assumptions about the arguments or memory,
and treat them as changed.

Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: kernel-hardening@lists.openwall.com
Link: https://lkml.kernel.org/r/20190618045503.39105-3-keescook@chromium.org
2019-06-22 11:55:22 +02:00
..
acpi treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 430 2019-06-05 17:37:16 +02:00
apic treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 223 2019-05-30 11:29:55 -07:00
cpu x86/asm: Pin sensitive CR4 bits 2019-06-22 11:55:22 +02:00
fpu x86/fpu: Don't use current->mm to check for a kthread 2019-06-13 20:57:49 +02:00
kprobes treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
.gitignore
alternative.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
amd_gart_64.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 213 2019-05-30 11:29:54 -07:00
amd_nb.c x86/amd_nb: Add PCI device IDs for family 17h, model 30h 2018-11-07 21:36:09 +01:00
apb_timer.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 441 2019-06-05 17:37:17 +02:00
aperture_64.c x86/gart: Exclude GART aperture from kcore 2019-03-23 12:11:49 +01:00
apm_32.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 118 2019-05-24 17:39:02 +02:00
asm-offsets_32.c x86/entry/32: Load task stack from x86_tss.sp1 in SYSENTER handler 2018-07-20 01:11:36 +02:00
asm-offsets_64.c x86/irq/64: Split the IRQ stack into its own pages 2019-04-17 15:37:02 +02:00
asm-offsets.c x86/asm: Remove unused TASK_TI_flags from asm-offsets.c 2019-05-24 08:48:17 +02:00
audit_64.c
bootflag.c
check.c x86/headers: Fix -Wmissing-prototypes warning 2018-11-23 07:59:59 +01:00
cpuid.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 142 2019-05-30 11:25:17 -07:00
crash_dump_32.c
crash_dump_64.c x86: Fix various typos in comments 2018-12-03 10:49:13 +01:00
crash.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
devicetree.c x86/headers: Fix -Wmissing-prototypes warning 2018-11-23 07:59:59 +01:00
doublefault.c
dumpstack_32.c x86/irq/32: Rename hard/softirq_stack to hard/softirq_stack_ptr 2019-04-17 15:24:18 +02:00
dumpstack_64.c x86/irq/64: Rename irq_stack_ptr to hardirq_stack_ptr 2019-04-17 15:27:10 +02:00
dumpstack.c x86/process: Don't mix user/kernel regs in 64bit __show_regs() 2018-09-06 14:33:12 +02:00
e820.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
early_printk.c efi/x86: Convert x86 EFI earlyprintk into generic earlycon implementation 2019-02-04 08:27:30 +01:00
early-quirks.c x86/gpu: add ElkhartLake to gen11 early quirks 2019-04-01 10:29:32 -07:00
ebda.c
eisa.c x86/EISA: Don't probe EISA bus for Xen PV guests 2018-09-11 23:36:50 +02:00
espfix_64.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 288 2019-06-05 17:36:37 +02:00
ftrace_32.S ftrace/x86: Remove mcount support 2019-05-10 12:33:09 -04:00
ftrace_64.S ftrace/x86: Remove mcount support 2019-05-10 12:33:09 -04:00
ftrace.c The major changes in this tracing update includes: 2019-05-15 16:05:47 -07:00
head32.c x86/boot: Mostly revert commit ae7e1238e6 ("Add ACPI RSDP address to setup_header") 2018-11-20 09:43:10 +01:00
head64.c x86/boot: Mostly revert commit ae7e1238e6 ("Add ACPI RSDP address to setup_header") 2018-11-20 09:43:10 +01:00
head_32.S x86/pgtable/32: Allocate 8k page-tables when PTI is enabled 2018-07-20 01:11:41 +02:00
head_64.S x86/irq/64: Split the IRQ stack into its own pages 2019-04-17 15:37:02 +02:00
hpet.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
hw_breakpoint.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
i8237.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
i8253.c
i8259.c x86: Don't include linux/irq.h from asm/hardirq.h 2018-08-05 09:53:13 +02:00
idt.c x86/exceptions: Disconnect IST index and stack order 2019-04-17 15:01:09 +02:00
ima_arch.c x86/ima: Check EFI_RUNTIME_SERVICES before using 2019-05-19 20:27:12 -04:00
io_delay.c
ioport.c
irq_32.c x86/irq/32: Handle irq stack allocation failure proper 2019-04-17 15:31:42 +02:00
irq_64.c x86/irq/64: Remove stack overflow debug code 2019-04-17 15:41:48 +02:00
irq_work.c
irq.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
irqflags.S
irqinit.c x86/irq/32: Handle irq stack allocation failure proper 2019-04-17 15:31:42 +02:00
itmt.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 441 2019-06-05 17:37:17 +02:00
jailhouse.c x86/headers: Fix -Wmissing-prototypes warning 2018-11-23 07:59:59 +01:00
jump_label.c x86/jump-label: Remove support for custom text poker 2019-04-30 12:37:55 +02:00
kdebugfs.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 428 2019-06-05 17:37:16 +02:00
kexec-bzimage64.c Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security 2019-03-10 17:32:04 -07:00
kgdb.c x86/kgdb: Return 0 from kgdb_arch_set_breakpoint() 2019-06-12 18:52:44 +02:00
ksysfs.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 428 2019-06-05 17:37:16 +02:00
kvm.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 19 2019-05-21 11:28:46 +02:00
kvmclock.c x86: kvmguest: use TSC clocksource if invariant TSC is exposed 2019-02-20 22:48:52 +01:00
ldt.c x86: Convert some slow-path static_cpu_has() callers to boot_cpu_has() 2019-04-08 12:13:34 +02:00
livepatch.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 13 2019-05-21 11:28:45 +02:00
machine_kexec_32.c x86/kexec: Allocate 8k PGDs for PTI 2018-07-30 13:53:48 +02:00
machine_kexec_64.c x86/kdump: Export the SME mask to vmcoreinfo 2019-01-11 16:09:25 +01:00
Makefile treewide: prefix header search paths with $(srctree)/ 2019-05-18 11:49:57 +09:00
mmconf-fam10h_64.c
module.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
mpparse.c x86/mm: Don't leak kernel addresses 2019-03-19 12:10:56 +01:00
msr.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 142 2019-05-30 11:25:17 -07:00
nmi_selftest.c
nmi.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
paravirt_patch_32.c x86/paravirt: Remove unused _paravirt_ident_32 2018-10-30 09:55:31 +01:00
paravirt_patch_64.c x86/paravirt: Remove unused _paravirt_ident_32 2018-10-30 09:55:31 +01:00
paravirt-spinlocks.c x86/paravirt: Use a single ops structure 2018-09-03 16:50:35 +02:00
paravirt.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 102 2019-05-24 17:39:00 +02:00
pci-calgary_64.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
pci-dma.c x86/dma: Remove the x86_dma_fallback_dev hack 2019-04-08 17:52:46 +02:00
pci-iommu_table.c x86/iommu: Use NULL instead of 0 2018-08-02 14:33:19 +02:00
pci-swiotlb.c dma-direct: merge swiotlb_dma_ops into the dma_direct code 2018-12-13 21:06:17 +01:00
pcspeaker.c x86/platform/pcspeaker: Use PTR_ERR_OR_ZERO() to fix ptr_ret.cocci warning 2018-07-24 09:46:42 +02:00
perf_regs.c perf/x86: Support outputting XMM registers 2019-04-16 12:19:36 +02:00
platform-quirks.c
pmem.c
probe_roms.c
process_32.c Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2019-05-07 10:24:10 -07:00
process_64.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
process.c Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2019-05-07 10:24:10 -07:00
process.h x86/speculation: Change misspelled STIPB to STIBP 2018-12-06 11:49:15 +01:00
ptrace.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
pvclock.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 102 2019-05-24 17:39:00 +02:00
quirks.c x86/headers: Fix -Wmissing-prototypes warning 2018-11-23 07:59:59 +01:00
reboot_fixups_32.c
reboot.c Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2019-05-06 15:32:35 -07:00
relocate_kernel_32.S
relocate_kernel_64.S
resource.c
rtc.c
setup_percpu.c x86/irq/64: Split the IRQ stack into its own pages 2019-04-17 15:37:02 +02:00
setup.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
signal_compat.c
signal.c Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2019-05-07 10:24:10 -07:00
smp.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 82 2019-05-24 17:37:52 +02:00
smpboot.c x86/asm: Pin sensitive CR4 bits 2019-06-22 11:55:22 +02:00
stacktrace.c x86/stacktrace: Use common infrastructure 2019-04-29 12:37:57 +02:00
step.c
sys_x86_64.c x86/compat: Adjust in_compat_syscall() to generic code under !COMPAT 2018-11-01 12:59:25 +01:00
sysfb_efi.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sysfb_simplefb.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sysfb.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
tboot.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 335 2019-06-05 17:37:06 +02:00
tce_64.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
time.c Merge branch 'x86-vdso-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2018-10-23 19:07:25 +01:00
tls.c
tls.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 193 2019-05-30 11:29:21 -07:00
topology.c x86/topology: Make DEBUG_HOTPLUG_CPU0 pr_info() more descriptive 2019-04-19 19:42:57 +02:00
trace_clock.c
tracepoint.c x86/kernel: Fix more -Wmissing-prototypes warnings 2018-12-08 12:24:35 +01:00
traps.c x86/speculation/mds: Revert CPU buffer clear on double fault exit 2019-05-16 09:05:11 +02:00
tsc_msr.c x86/cpu: Sanitize FAM6_ATOM naming 2018-10-02 10:14:32 +02:00
tsc_sync.c
tsc.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
umip.c signal/x86: Use force_sig_fault where appropriate 2018-09-21 15:30:54 +02:00
unwind_frame.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
unwind_guess.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
unwind_orc.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
uprobes.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
verify_cpu.S
vm86_32.c x86: Convert some slow-path static_cpu_has() callers to boot_cpu_has() 2019-04-08 12:13:34 +02:00
vmlinux.lds.S Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2019-05-06 16:13:31 -07:00
vsmp_64.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 346 2019-06-05 17:37:08 +02:00
x86_init.c x86/acpi, x86/boot: Take RSDP address for boot params if available 2018-10-10 10:44:22 +02:00