mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 20:22:46 +00:00
hv: cve hotfix: Disable RRSBA on platform using retpoline
For platform that supports RRSBA (Restricted Return Stack Buffer Alternate), using retpoline may not be sufficient to guard against branch history injection or intra-mode branch target injection. RRSBA must be disabled to prevent CPUs from using alternate predictors for RETs. Quoting Intel CVE-2022-0001/CVE-2022-0002: Where software is using retpoline as a mitigation for BHI or intra-mode BTI, and the processor both enumerates RRSBA and enumerates RRSBA_DIS controls, it should disable this behavior. ... Software using retpoline as a mitigation for BHI or intra-mode BTI should use these new indirect predictor controls to disable alternate predictors for RETs. See: https://www.intel.com/content/www/us/en/developer/articles/technical/ software-security-guidance/technical-documentation/branch-history-injection.html Tracked-On: #7907 Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
This commit is contained in:
parent
22dbb6baed
commit
77cf205e93
@ -231,6 +231,10 @@ void init_pcpu_post(uint16_t pcpu_id)
|
|||||||
|
|
||||||
init_pcpu_xsave();
|
init_pcpu_xsave();
|
||||||
|
|
||||||
|
#ifdef CONFIG_RETPOLINE
|
||||||
|
disable_rrsba();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pcpu_id == BSP_CPU_ID) {
|
if (pcpu_id == BSP_CPU_ID) {
|
||||||
/* Print Hypervisor Banner */
|
/* Print Hypervisor Banner */
|
||||||
print_hv_banner();
|
print_hv_banner();
|
||||||
|
@ -355,6 +355,9 @@ void init_pcpu_capabilities(void)
|
|||||||
&boot_cpu_data.cpuid_leaves[FEAT_7_0_ECX],
|
&boot_cpu_data.cpuid_leaves[FEAT_7_0_ECX],
|
||||||
&boot_cpu_data.cpuid_leaves[FEAT_7_0_EDX]);
|
&boot_cpu_data.cpuid_leaves[FEAT_7_0_EDX]);
|
||||||
|
|
||||||
|
cpuid_subleaf(CPUID_EXTEND_FEATURE, 0x2U, &unused, &unused, &unused,
|
||||||
|
&boot_cpu_data.cpuid_leaves[FEAT_7_2_EDX]);
|
||||||
|
|
||||||
cpuid_subleaf(CPUID_MAX_EXTENDED_FUNCTION, 0x0U,
|
cpuid_subleaf(CPUID_MAX_EXTENDED_FUNCTION, 0x0U,
|
||||||
&boot_cpu_data.extended_cpuid_level,
|
&boot_cpu_data.extended_cpuid_level,
|
||||||
&unused, &unused, &unused);
|
&unused, &unused, &unused);
|
||||||
|
@ -44,6 +44,42 @@ static void detect_ibrs(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_RETPOLINE
|
||||||
|
/* For platform that supports RRSBA (Restricted Return Stack Buffer Alternate),
|
||||||
|
* using retpoline may not be sufficient to guard against branch history injection (BHI)
|
||||||
|
* or Intra-mode branch target injection (IMBTI). RRSBA must be disabled to
|
||||||
|
* prevent CPUs from using alternate predictors for RETs.
|
||||||
|
*
|
||||||
|
* Quoting Intel CVE-2022-0001/CVE-2022-0002 documentation:
|
||||||
|
*
|
||||||
|
* Where software is using retpoline as a mitigation for BHI or intra-mode BTI,
|
||||||
|
* and the processor both enumerates RRSBA and enumerates RRSBA_DIS controls,
|
||||||
|
* it should disable this behavior.
|
||||||
|
* ...
|
||||||
|
* Software using retpoline as a mitigation for BHI or intra-mode BTI should use
|
||||||
|
* these new indirect predictor controls to disable alternate predictors for RETs.
|
||||||
|
*
|
||||||
|
* See: https://www.intel.com/content/www/us/en/developer/articles/technical/
|
||||||
|
* software-security-guidance/technical-documentation/branch-history-injection.html
|
||||||
|
*/
|
||||||
|
void disable_rrsba(void) {
|
||||||
|
uint64_t v, x86_arch_caps;
|
||||||
|
bool rrsba_behavior = false;
|
||||||
|
|
||||||
|
if (pcpu_has_cap(X86_FEATURE_ARCH_CAP)) {
|
||||||
|
x86_arch_caps = msr_read(MSR_IA32_ARCH_CAPABILITIES);
|
||||||
|
rrsba_behavior = ((x86_arch_caps & IA32_ARCH_CAP_RESTRICTED_RSBA) != 0UL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rrsba_behavior && pcpu_has_cap(X86_FEATURE_RRSBA_CTRL)) {
|
||||||
|
v = msr_read(MSR_IA32_SPEC_CTRL);
|
||||||
|
/* Setting SPEC_RRSBA_DIS_S disables RRSBA behavior for CPL0/1/2 */
|
||||||
|
v |= SPEC_RRSBA_DIS_S;
|
||||||
|
msr_write(MSR_IA32_SPEC_CTRL, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int32_t get_ibrs_type(void)
|
int32_t get_ibrs_type(void)
|
||||||
{
|
{
|
||||||
return ibrs_type;
|
return ibrs_type;
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
#define FEAT_D_1_EAX 11U /* CPUID[D][1].EAX */
|
#define FEAT_D_1_EAX 11U /* CPUID[D][1].EAX */
|
||||||
#define FEAT_D_1_ECX 13U /* CPUID[D][1].ECX */
|
#define FEAT_D_1_ECX 13U /* CPUID[D][1].ECX */
|
||||||
#define FEAT_D_1_EDX 14U /* CPUID[D][1].EDX */
|
#define FEAT_D_1_EDX 14U /* CPUID[D][1].EDX */
|
||||||
#define FEATURE_WORDS 15U
|
#define FEAT_7_2_EDX 15U /* CPUID[EAX=7,ECX=2].EDX */
|
||||||
|
#define FEATURE_WORDS 16U
|
||||||
|
|
||||||
struct cpuinfo_x86 {
|
struct cpuinfo_x86 {
|
||||||
/* SDM 2-2 Vol.4 Table 2-1 uses DisplayFamily_DisplayModel to
|
/* SDM 2-2 Vol.4 Table 2-1 uses DisplayFamily_DisplayModel to
|
||||||
|
@ -92,6 +92,9 @@
|
|||||||
#define X86_FEATURE_CORE_CAP ((FEAT_7_0_EDX << 5U) + 30U)
|
#define X86_FEATURE_CORE_CAP ((FEAT_7_0_EDX << 5U) + 30U)
|
||||||
#define X86_FEATURE_SSBD ((FEAT_7_0_EDX << 5U) + 31U)
|
#define X86_FEATURE_SSBD ((FEAT_7_0_EDX << 5U) + 31U)
|
||||||
|
|
||||||
|
/* Intel-defined CPU features, CPUID level 0x00000007, sub 0x2 (EDX)*/
|
||||||
|
#define X86_FEATURE_RRSBA_CTRL ((FEAT_7_2_EDX << 5U) + 2U)
|
||||||
|
|
||||||
/* Intel-defined CPU features, CPUID level 0x80000001 (EDX)*/
|
/* Intel-defined CPU features, CPUID level 0x80000001 (EDX)*/
|
||||||
#define X86_FEATURE_NX ((FEAT_8000_0001_EDX << 5U) + 20U)
|
#define X86_FEATURE_NX ((FEAT_8000_0001_EDX << 5U) + 20U)
|
||||||
#define X86_FEATURE_PAGE1GB ((FEAT_8000_0001_EDX << 5U) + 26U)
|
#define X86_FEATURE_PAGE1GB ((FEAT_8000_0001_EDX << 5U) + 26U)
|
||||||
|
@ -657,6 +657,7 @@ void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu);
|
|||||||
/* SPEC & PRED bit */
|
/* SPEC & PRED bit */
|
||||||
#define SPEC_ENABLE_IBRS (1U << 0U)
|
#define SPEC_ENABLE_IBRS (1U << 0U)
|
||||||
#define SPEC_ENABLE_STIBP (1U << 1U)
|
#define SPEC_ENABLE_STIBP (1U << 1U)
|
||||||
|
#define SPEC_RRSBA_DIS_S (1U << 6U)
|
||||||
#define PRED_SET_IBPB (1U << 0U)
|
#define PRED_SET_IBPB (1U << 0U)
|
||||||
|
|
||||||
/* IA32 ARCH Capabilities bit */
|
/* IA32 ARCH Capabilities bit */
|
||||||
@ -667,6 +668,7 @@ void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu);
|
|||||||
#define IA32_ARCH_CAP_SSB_NO (1UL << 4U)
|
#define IA32_ARCH_CAP_SSB_NO (1UL << 4U)
|
||||||
#define IA32_ARCH_CAP_MDS_NO (1UL << 5U)
|
#define IA32_ARCH_CAP_MDS_NO (1UL << 5U)
|
||||||
#define IA32_ARCH_CAP_IF_PSCHANGE_MC_NO (1UL << 6U)
|
#define IA32_ARCH_CAP_IF_PSCHANGE_MC_NO (1UL << 6U)
|
||||||
|
#define IA32_ARCH_CAP_RESTRICTED_RSBA (1UL << 19U)
|
||||||
|
|
||||||
/* Flush L1 D-cache */
|
/* Flush L1 D-cache */
|
||||||
#define IA32_L1D_FLUSH (1UL << 0U)
|
#define IA32_L1D_FLUSH (1UL << 0U)
|
||||||
|
@ -23,6 +23,7 @@ bool check_cpu_security_cap(void);
|
|||||||
void cpu_internal_buffers_clear(void);
|
void cpu_internal_buffers_clear(void);
|
||||||
bool is_ept_force_4k_ipage(void);
|
bool is_ept_force_4k_ipage(void);
|
||||||
uint64_t get_random_value(void);
|
uint64_t get_random_value(void);
|
||||||
|
void disable_rrsba(void);
|
||||||
|
|
||||||
#ifdef STACK_PROTECTOR
|
#ifdef STACK_PROTECTOR
|
||||||
struct stack_canary {
|
struct stack_canary {
|
||||||
|
Loading…
Reference in New Issue
Block a user