mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86: Introduce support for CET-IBT
CET Indirect Branch Tracking is a hardware feature designed to provide
forward-edge control flow integrity, protecting against jump/call oriented
programming.
IBT requires the placement of endbr{32,64} instructions at the target of every
indirect call/jmp, and every entrypoint.
However, the default -fcf-protection=branch places an endbr{32,64} on every
function which far more than necessary, and reduces the quantity of protection
afforded. Therefore, we use manual placement using the cf_check attribute.
It is necessary to check for both compiler and assembler support, as the
notrack prefix can be emitted in certain cases.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
7764fd93cf
commit
3667f7f8f7
11 files changed
+44
-1
No files matched your search
@@ -190,7 +190,6 @@ APPEND_CFLAGS += $(foreach i, $(APPEND_INCLUDES), -I$(i))
|
||||
|
||||
EMBEDDED_EXTRA_CFLAGS := -nopie -fno-stack-protector -fno-stack-protector-all
|
||||
EMBEDDED_EXTRA_CFLAGS += -fno-exceptions -fno-asynchronous-unwind-tables
|
||||
EMBEDDED_EXTRA_CFLAGS += -fcf-protection=none
|
||||
|
||||
XEN_EXTFILES_URL ?= http://xenbits.xen.org/xen-extfiles
|
||||
# All the files at that location were downloaded from elsewhere on
|
||||
|
||||
@@ -6,6 +6,8 @@ TARGET := hvmloader/hvmloader
|
||||
INST_DIR := $(DESTDIR)$(XENFIRMWAREDIR)
|
||||
DEBG_DIR := $(DESTDIR)$(DEBUG_DIR)$(XENFIRMWAREDIR)
|
||||
|
||||
EMBEDDED_EXTRA_CFLAGS += -fcf-protection=none
|
||||
|
||||
SUBDIRS-y :=
|
||||
SUBDIRS-$(CONFIG_OVMF) += ovmf-dir
|
||||
SUBDIRS-$(CONFIG_SEABIOS) += seabios-dir
|
||||
|
||||
@@ -8,6 +8,8 @@ typedef int decompress_fn(unsigned char *inbuf, unsigned int len,
|
||||
void (*error)(const char *x));
|
||||
#endif
|
||||
|
||||
#define cf_check /* No Control Flow Integriy checking */
|
||||
|
||||
int xc_dom_decompress_unsafe(
|
||||
decompress_fn fn, struct xc_dom_image *dom, void **blob, size_t *size)
|
||||
__attribute__((visibility("internal")));
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
#define likely(x) __builtin_expect(!!(x), true)
|
||||
#define unlikely(x) __builtin_expect(!!(x), false)
|
||||
|
||||
#define cf_check /* No Control Flow Integriy checking */
|
||||
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
typeof(((type *)0)->member) *mptr__ = (ptr); \
|
||||
(type *)((char *)mptr__ - offsetof(type, member)); \
|
||||
|
||||
@@ -40,6 +40,11 @@ config HAS_AS_CET_SS
|
||||
# binutils >= 2.29 or LLVM >= 6
|
||||
def_bool $(as-instr,wrssq %rax$(comma)0;setssbsy)
|
||||
|
||||
config HAS_CC_CET_IBT
|
||||
# GCC >= 9 and binutils >= 2.29
|
||||
# Retpoline check to work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93654
|
||||
def_bool $(cc-option,-fcf-protection=branch -mmanual-endbr -mindirect-branch=thunk-extern) && $(as-instr,endbr64)
|
||||
|
||||
menu "Architecture Features"
|
||||
|
||||
source "arch/Kconfig"
|
||||
@@ -125,6 +130,18 @@ config XEN_SHSTK
|
||||
When CET-SS is active, 32bit PV guests cannot be used. Backwards
|
||||
compatiblity can be provided via the PV Shim mechanism.
|
||||
|
||||
config XEN_IBT
|
||||
bool "Supervisor Indirect Branch Tracking"
|
||||
depends on HAS_CC_CET_IBT
|
||||
default y
|
||||
help
|
||||
Control-flow Enforcement Technology (CET) is a set of features in
|
||||
hardware designed to combat Return-oriented Programming (ROP, also
|
||||
call/jump COP/JOP) attacks. Indirect Branch Tracking is one CET
|
||||
feature designed to provide function pointer protection.
|
||||
|
||||
This option arranges for Xen to use CET-IBT for its own protection.
|
||||
|
||||
config SHADOW_PAGING
|
||||
bool "Shadow Paging"
|
||||
default !PV_SHIM_EXCLUSIVE
|
||||
|
||||
@@ -52,6 +52,12 @@ CFLAGS-$(CONFIG_CC_IS_GCC) += -fno-jump-tables
|
||||
CFLAGS-$(CONFIG_CC_IS_CLANG) += -mretpoline-external-thunk
|
||||
endif
|
||||
|
||||
ifdef CONFIG_XEN_IBT
|
||||
CFLAGS += -fcf-protection=branch -mmanual-endbr
|
||||
else
|
||||
$(call cc-option-add,CFLAGS,CC,-fcf-protection=none)
|
||||
endif
|
||||
|
||||
# If supported by the compiler, reduce stack alignment to 8 bytes. But allow
|
||||
# this to be overridden elsewhere.
|
||||
$(call cc-option-add,CFLAGS_stack_boundary,CC,-mpreferred-stack-boundary=3)
|
||||
|
||||
@@ -8,6 +8,7 @@ CONFIG_NR_CPUS=32
|
||||
CONFIG_EXPERT=y
|
||||
# Disable features not used by the PV shim
|
||||
# CONFIG_XEN_SHSTK is not set
|
||||
# CONFIG_XEN_IBT is not set
|
||||
# CONFIG_GRANT_TABLE is not set
|
||||
# CONFIG_HYPFS is not set
|
||||
# CONFIG_BIGMEM is not set
|
||||
|
||||
@@ -57,6 +57,12 @@
|
||||
INDIRECT_BRANCH jmp \arg
|
||||
.endm
|
||||
|
||||
#ifdef CONFIG_XEN_IBT
|
||||
# define ENDBR64 endbr64
|
||||
#else
|
||||
# define ENDBR64
|
||||
#endif
|
||||
|
||||
.macro guest_access_mask_ptr ptr:req, scratch1:req, scratch2:req
|
||||
#if defined(CONFIG_SPECULATIVE_HARDEN_GUEST_ACCESS)
|
||||
/*
|
||||
|
||||
@@ -152,6 +152,7 @@
|
||||
#define cpu_has_nscb boot_cpu_has(X86_FEATURE_NSCB)
|
||||
#define cpu_has_xen_lbr boot_cpu_has(X86_FEATURE_XEN_LBR)
|
||||
#define cpu_has_xen_shstk boot_cpu_has(X86_FEATURE_XEN_SHSTK)
|
||||
#define cpu_has_xen_ibt boot_cpu_has(X86_FEATURE_XEN_IBT)
|
||||
|
||||
#define cpu_has_msr_tsc_aux (cpu_has_rdtscp || cpu_has_rdpid)
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ XEN_CPUFEATURE(SC_VERW_PV, X86_SYNTH(23)) /* VERW used by Xen for PV */
|
||||
XEN_CPUFEATURE(SC_VERW_HVM, X86_SYNTH(24)) /* VERW used by Xen for HVM */
|
||||
XEN_CPUFEATURE(SC_VERW_IDLE, X86_SYNTH(25)) /* VERW used by Xen for idle */
|
||||
XEN_CPUFEATURE(XEN_SHSTK, X86_SYNTH(26)) /* Xen uses CET Shadow Stacks */
|
||||
XEN_CPUFEATURE(XEN_IBT, X86_SYNTH(27)) /* Xen uses CET Indirect Branch Tracking */
|
||||
|
||||
/* Bug words follow the synthetic words. */
|
||||
#define X86_NR_BUG 1
|
||||
|
||||
@@ -37,6 +37,12 @@
|
||||
# define nocall
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XEN_IBT
|
||||
# define cf_check __attribute__((__cf_check__))
|
||||
#else
|
||||
# define cf_check
|
||||
#endif
|
||||
|
||||
#if (!defined(__clang__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5))
|
||||
#define unreachable() do {} while (1)
|
||||
#else
|
||||
|
||||