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:
Yifan Liu 2022-07-19 00:31:23 +00:00 committed by acrnsi-robot
parent de8877e71a
commit 4f4da08490
7 changed files with 51 additions and 1 deletions

View File

@ -231,6 +231,10 @@ void init_pcpu_post(uint16_t pcpu_id)
init_pcpu_xsave();
#ifdef CONFIG_RETPOLINE
disable_rrsba();
#endif
if (pcpu_id == BSP_CPU_ID) {
/* Print Hypervisor Banner */
print_hv_banner();

View File

@ -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_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,
&boot_cpu_data.extended_cpuid_level,
&unused, &unused, &unused);

View File

@ -44,6 +44,42 @@ static void detect_ibrs(void)
#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)
{
return ibrs_type;

View File

@ -29,7 +29,8 @@
#define FEAT_D_1_EAX 11U /* CPUID[D][1].EAX */
#define FEAT_D_1_ECX 13U /* CPUID[D][1].ECX */
#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 {
/* SDM 2-2 Vol.4 Table 2-1 uses DisplayFamily_DisplayModel to

View File

@ -92,6 +92,9 @@
#define X86_FEATURE_CORE_CAP ((FEAT_7_0_EDX << 5U) + 30U)
#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)*/
#define X86_FEATURE_NX ((FEAT_8000_0001_EDX << 5U) + 20U)
#define X86_FEATURE_PAGE1GB ((FEAT_8000_0001_EDX << 5U) + 26U)

View File

@ -657,6 +657,7 @@ void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu);
/* SPEC & PRED bit */
#define SPEC_ENABLE_IBRS (1U << 0U)
#define SPEC_ENABLE_STIBP (1U << 1U)
#define SPEC_RRSBA_DIS_S (1U << 6U)
#define PRED_SET_IBPB (1U << 0U)
/* 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_MDS_NO (1UL << 5U)
#define IA32_ARCH_CAP_IF_PSCHANGE_MC_NO (1UL << 6U)
#define IA32_ARCH_CAP_RESTRICTED_RSBA (1UL << 19U)
/* Flush L1 D-cache */
#define IA32_L1D_FLUSH (1UL << 0U)

View File

@ -23,6 +23,7 @@ bool check_cpu_security_cap(void);
void cpu_internal_buffers_clear(void);
bool is_ept_force_4k_ipage(void);
uint64_t get_random_value(void);
void disable_rrsba(void);
#ifdef STACK_PROTECTOR
struct stack_canary {