hv: Hide CET feature from guest VM

Return-oriented programming (ROP), and similarly CALL/JMP-oriented
programming (COP/JOP), have been the prevalent attack methodologies for
stealth exploit writers targeting vulnerabilities in programs.

CET (Control-flow Enforcement Technology) provides the following
capabilities to defend against ROP/COP/JOP style control-flow subversion
attacks:
 * Shadow stack: Return address protection to defend against ROP.
 * Indirect branch tracking: Free branch protection to defend against
   COP/JOP

The full support of CET for Linux kernel has not been merged yet. As the
first stage, hide CET from guest VM.

Tracked-On: #5074
Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com>
Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
This commit is contained in:
Shuo A Liu 2020-07-08 19:39:07 +08:00 committed by wenlingz
parent 5e605e0daf
commit ac598b0856
6 changed files with 55 additions and 7 deletions

View File

@ -128,6 +128,10 @@ static void init_vcpuid_entry(uint32_t leaf, uint32_t subleaf,
/* mask Intel Processor Trace, since 14h is disabled */ /* mask Intel Processor Trace, since 14h is disabled */
entry->ebx &= ~CPUID_EBX_PROC_TRC; entry->ebx &= ~CPUID_EBX_PROC_TRC;
/* mask CET shadow stack and indirect branch tracking */
entry->ecx &= ~CPUID_ECX_CET_SS;
entry->edx &= ~CPUID_EDX_CET_IBT;
} else { } else {
entry->eax = 0U; entry->eax = 0U;
entry->ebx = 0U; entry->ebx = 0U;
@ -494,12 +498,26 @@ static void guest_cpuid_0dh(__unused struct acrn_vcpu *vcpu, uint32_t *eax, uint
*edx = 0U; *edx = 0U;
} else { } else {
cpuid_subleaf(0x0dU, subleaf, eax, ebx, ecx, edx); cpuid_subleaf(0x0dU, subleaf, eax, ebx, ecx, edx);
if (subleaf == 0U) { switch (subleaf) {
case 0U:
/* SDM Vol.1 17-2, On processors that do not support Intel MPX, /* SDM Vol.1 17-2, On processors that do not support Intel MPX,
* CPUID.(EAX=0DH,ECX=0):EAX[3] and * CPUID.(EAX=0DH,ECX=0):EAX[3] and
* CPUID.(EAX=0DH,ECX=0):EAX[4] will both be 0 */ * CPUID.(EAX=0DH,ECX=0):EAX[4] will both be 0 */
*eax &= ~ CPUID_EAX_XCR0_BNDREGS; *eax &= ~(CPUID_EAX_XCR0_BNDREGS | CPUID_EAX_XCR0_BNDCSR);
*eax &= ~ CPUID_EAX_XCR0_BNDCSR; break;
case 1U:
*ecx &= ~(CPUID_ECX_CET_U_STATE | CPUID_ECX_CET_S_STATE);
break;
case 11U:
case 12U:
*eax = 0U;
*ebx = 0U;
*ecx = 0U;
*edx = 0U;
break;
default:
/* No emulation for other leaves */
break;
} }
} }
} }

View File

@ -27,13 +27,13 @@
CR0_NE | CR0_ET | CR0_TS | CR0_EM | CR0_MP | CR0_PE) CR0_NE | CR0_ET | CR0_TS | CR0_EM | CR0_MP | CR0_PE)
/* CR4 bits hv want to trap to track status change */ /* CR4 bits hv want to trap to track status change */
#define CR4_TRAP_MASK (CR4_PSE | CR4_PAE | CR4_VMXE | CR4_SMEP | CR4_SMAP | CR4_PKE) #define CR4_TRAP_MASK (CR4_PSE | CR4_PAE | CR4_VMXE | CR4_SMEP | CR4_SMAP | CR4_PKE | CR4_CET)
#define CR4_RESERVED_MASK ~(CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | \ #define CR4_RESERVED_MASK ~(CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | \
CR4_PAE | CR4_MCE | CR4_PGE | CR4_PCE | \ CR4_PAE | CR4_MCE | CR4_PGE | CR4_PCE | \
CR4_OSFXSR | CR4_PCIDE | CR4_OSXSAVE | \ CR4_OSFXSR | CR4_PCIDE | CR4_OSXSAVE | \
CR4_SMEP | CR4_FSGSBASE | CR4_VMXE | \ CR4_SMEP | CR4_FSGSBASE | CR4_VMXE | \
CR4_OSXMMEXCPT | CR4_SMAP | CR4_PKE | \ CR4_OSXMMEXCPT | CR4_SMAP | CR4_PKE | \
CR4_SMXE | CR4_UMIP) CR4_SMXE | CR4_UMIP | CR4_CET)
/* PAE PDPTE bits 1 ~ 2, 5 ~ 8 are always reserved */ /* PAE PDPTE bits 1 ~ 2, 5 ~ 8 are always reserved */
#define PAE_PDPTE_FIXED_RESVD_BITS 0x00000000000001E6UL #define PAE_PDPTE_FIXED_RESVD_BITS 0x00000000000001E6UL
@ -256,7 +256,7 @@ static bool is_cr4_write_valid(struct acrn_vcpu *vcpu, uint64_t cr4)
ret = false; ret = false;
} else { } else {
/* Do NOT support nested guest, nor SMX */ /* Do NOT support nested guest, nor SMX */
if (((cr4 & CR4_VMXE) != 0UL) || ((cr4 & CR4_SMXE) != 0UL)) { if (((cr4 & CR4_VMXE) != 0UL) || ((cr4 & CR4_SMXE) != 0UL) || ((cr4 & CR4_CET) != 0UL)) {
ret = false; ret = false;
} else { } else {
if (is_long_mode(vcpu)) { if (is_long_mode(vcpu)) {
@ -304,6 +304,7 @@ static bool is_cr4_write_valid(struct acrn_vcpu *vcpu, uint64_t cr4)
* - SMEP (20) Flexible to guest * - SMEP (20) Flexible to guest
* - SMAP (21) Flexible to guest * - SMAP (21) Flexible to guest
* - PKE (22) Flexible to guest * - PKE (22) Flexible to guest
* - CET (23) Trapped to hide from guest
*/ */
static void vmx_write_cr4(struct acrn_vcpu *vcpu, uint64_t cr4) static void vmx_write_cr4(struct acrn_vcpu *vcpu, uint64_t cr4)
{ {

View File

@ -80,7 +80,7 @@ static const uint32_t mtrr_msrs[NUM_MTRR_MSRS] = {
}; };
/* Following MSRs are intercepted, but it throws GPs for any guest accesses */ /* Following MSRs are intercepted, but it throws GPs for any guest accesses */
#define NUM_UNSUPPORTED_MSRS 104U #define NUM_UNSUPPORTED_MSRS 111U
static const uint32_t unsupported_msrs[NUM_UNSUPPORTED_MSRS] = { static const uint32_t unsupported_msrs[NUM_UNSUPPORTED_MSRS] = {
/* Variable MTRRs are not supported */ /* Variable MTRRs are not supported */
MSR_IA32_MTRR_PHYSBASE_0, MSR_IA32_MTRR_PHYSBASE_0,
@ -221,6 +221,19 @@ static const uint32_t unsupported_msrs[NUM_UNSUPPORTED_MSRS] = {
MSR_PRMRR_VALID_CONFIG, MSR_PRMRR_VALID_CONFIG,
MSR_UNCORE_PRMRR_PHYS_BASE, MSR_UNCORE_PRMRR_PHYS_BASE,
MSR_UNCORE_PRMRR_PHYS_MASK, MSR_UNCORE_PRMRR_PHYS_MASK,
/*
* CET disabled:
* CPUID.07H.ECX[7] (CPUID_ECX_CET_SS)
* CPUID.07H.EDX[20] (CPUID_ECX_CET_IBT)
*/
MSR_IA32_U_CET,
MSR_IA32_S_CET,
MSR_IA32_PL0_SSP,
MSR_IA32_PL1_SSP,
MSR_IA32_PL2_SSP,
MSR_IA32_PL3_SSP,
MSR_IA32_INTERRUPT_SSP_TABLE_ADDR,
}; };
/* emulated_guest_msrs[] shares same indexes with array vcpu->arch->guest_msrs[] */ /* emulated_guest_msrs[] shares same indexes with array vcpu->arch->guest_msrs[] */

View File

@ -84,6 +84,7 @@
#define CR4_SMEP (1UL<<20U) #define CR4_SMEP (1UL<<20U)
#define CR4_SMAP (1UL<<21U) #define CR4_SMAP (1UL<<21U)
#define CR4_PKE (1UL<<22U) /* Protect-key-enable */ #define CR4_PKE (1UL<<22U) /* Protect-key-enable */
#define CR4_CET (1UL<<23U) /* Control-flow Enforcement Technology enable */
/* XCR0_SSE */ /* XCR0_SSE */
#define XCR0_SSE (1UL<<1U) #define XCR0_SSE (1UL<<1U)

View File

@ -78,8 +78,12 @@
#define CPUID_EBX_SGX (1U<<2U) #define CPUID_EBX_SGX (1U<<2U)
/* CPUID.07H:EBX.MPX */ /* CPUID.07H:EBX.MPX */
#define CPUID_EBX_MPX (1U<<14U) #define CPUID_EBX_MPX (1U<<14U)
/* CPUID.07H:ECX.CET_SS */
#define CPUID_ECX_CET_SS (1U<<7U)
/* CPUID.07H:ECX.SGX_LC*/ /* CPUID.07H:ECX.SGX_LC*/
#define CPUID_ECX_SGX_LC (1U<<30U) #define CPUID_ECX_SGX_LC (1U<<30U)
/* CPUID.07H:EDX.CET_IBT */
#define CPUID_EDX_CET_IBT (1U<<20U)
/* CPUID.07H:EDX.IBRS_IBPB*/ /* CPUID.07H:EDX.IBRS_IBPB*/
#define CPUID_EDX_IBRS_IBPB (1U<<26U) #define CPUID_EDX_IBRS_IBPB (1U<<26U)
/* CPUID.07H:EDX.STIBP*/ /* CPUID.07H:EDX.STIBP*/
@ -100,6 +104,10 @@
#define CPUID_EAX_XCR0_BNDREGS (1U<<3U) #define CPUID_EAX_XCR0_BNDREGS (1U<<3U)
/* CPUID.0DH.EAX.XCR0_BNDCSR */ /* CPUID.0DH.EAX.XCR0_BNDCSR */
#define CPUID_EAX_XCR0_BNDCSR (1U<<4U) #define CPUID_EAX_XCR0_BNDCSR (1U<<4U)
/* CPUID.0DH.ECX.CET_U_STATE */
#define CPUID_ECX_CET_U_STATE (1U<<11U)
/* CPUID.0DH.ECX.CET_S_STATE */
#define CPUID_ECX_CET_S_STATE (1U<<12U)
/* CPUID.12H.EAX.SGX1 */ /* CPUID.12H.EAX.SGX1 */
#define CPUID_EAX_SGX1 (1U<<0U) #define CPUID_EAX_SGX1 (1U<<0U)
/* CPUID.12H.EAX.SGX2 */ /* CPUID.12H.EAX.SGX2 */

View File

@ -278,6 +278,13 @@
#define MSR_IA32_RTIT_ADDR3_A 0x00000586U #define MSR_IA32_RTIT_ADDR3_A 0x00000586U
#define MSR_IA32_RTIT_ADDR3_B 0x00000587U #define MSR_IA32_RTIT_ADDR3_B 0x00000587U
#define MSR_IA32_DS_AREA 0x00000600U #define MSR_IA32_DS_AREA 0x00000600U
#define MSR_IA32_U_CET 0x000006A0U
#define MSR_IA32_S_CET 0x000006A2U
#define MSR_IA32_PL0_SSP 0x000006A4U
#define MSR_IA32_PL1_SSP 0x000006A5U
#define MSR_IA32_PL2_SSP 0x000006A6U
#define MSR_IA32_PL3_SSP 0x000006A7U
#define MSR_IA32_INTERRUPT_SSP_TABLE_ADDR 0x000006A8U
#define MSR_IA32_TSC_DEADLINE 0x000006E0U #define MSR_IA32_TSC_DEADLINE 0x000006E0U
#define MSR_IA32_PM_ENABLE 0x00000770U #define MSR_IA32_PM_ENABLE 0x00000770U
#define MSR_IA32_HWP_CAPABILITIES 0x00000771U #define MSR_IA32_HWP_CAPABILITIES 0x00000771U