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:
parent
5e605e0daf
commit
ac598b0856
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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[] */
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue