Skip to content

Commit 77cf205

Browse files
yfliuuuacrnsi-robot
authored andcommitted
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 <[email protected]>
1 parent 22dbb6b commit 77cf205

File tree

7 files changed

+51
-1
lines changed

7 files changed

+51
-1
lines changed

hypervisor/arch/x86/cpu.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ void init_pcpu_post(uint16_t pcpu_id)
231231

232232
init_pcpu_xsave();
233233

234+
#ifdef CONFIG_RETPOLINE
235+
disable_rrsba();
236+
#endif
237+
234238
if (pcpu_id == BSP_CPU_ID) {
235239
/* Print Hypervisor Banner */
236240
print_hv_banner();

hypervisor/arch/x86/cpu_caps.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,9 @@ void init_pcpu_capabilities(void)
355355
&boot_cpu_data.cpuid_leaves[FEAT_7_0_ECX],
356356
&boot_cpu_data.cpuid_leaves[FEAT_7_0_EDX]);
357357

358+
cpuid_subleaf(CPUID_EXTEND_FEATURE, 0x2U, &unused, &unused, &unused,
359+
&boot_cpu_data.cpuid_leaves[FEAT_7_2_EDX]);
360+
358361
cpuid_subleaf(CPUID_MAX_EXTENDED_FUNCTION, 0x0U,
359362
&boot_cpu_data.extended_cpuid_level,
360363
&unused, &unused, &unused);

hypervisor/arch/x86/security.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,42 @@ static void detect_ibrs(void)
4444
#endif
4545
}
4646

47+
#ifdef CONFIG_RETPOLINE
48+
/* For platform that supports RRSBA (Restricted Return Stack Buffer Alternate),
49+
* using retpoline may not be sufficient to guard against branch history injection (BHI)
50+
* or Intra-mode branch target injection (IMBTI). RRSBA must be disabled to
51+
* prevent CPUs from using alternate predictors for RETs.
52+
*
53+
* Quoting Intel CVE-2022-0001/CVE-2022-0002 documentation:
54+
*
55+
* Where software is using retpoline as a mitigation for BHI or intra-mode BTI,
56+
* and the processor both enumerates RRSBA and enumerates RRSBA_DIS controls,
57+
* it should disable this behavior.
58+
* ...
59+
* Software using retpoline as a mitigation for BHI or intra-mode BTI should use
60+
* these new indirect predictor controls to disable alternate predictors for RETs.
61+
*
62+
* See: https://www.intel.com/content/www/us/en/developer/articles/technical/
63+
* software-security-guidance/technical-documentation/branch-history-injection.html
64+
*/
65+
void disable_rrsba(void) {
66+
uint64_t v, x86_arch_caps;
67+
bool rrsba_behavior = false;
68+
69+
if (pcpu_has_cap(X86_FEATURE_ARCH_CAP)) {
70+
x86_arch_caps = msr_read(MSR_IA32_ARCH_CAPABILITIES);
71+
rrsba_behavior = ((x86_arch_caps & IA32_ARCH_CAP_RESTRICTED_RSBA) != 0UL);
72+
}
73+
74+
if (rrsba_behavior && pcpu_has_cap(X86_FEATURE_RRSBA_CTRL)) {
75+
v = msr_read(MSR_IA32_SPEC_CTRL);
76+
/* Setting SPEC_RRSBA_DIS_S disables RRSBA behavior for CPL0/1/2 */
77+
v |= SPEC_RRSBA_DIS_S;
78+
msr_write(MSR_IA32_SPEC_CTRL, v);
79+
}
80+
}
81+
#endif
82+
4783
int32_t get_ibrs_type(void)
4884
{
4985
return ibrs_type;

hypervisor/include/arch/x86/asm/cpu_caps.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
#define FEAT_D_1_EAX 11U /* CPUID[D][1].EAX */
3030
#define FEAT_D_1_ECX 13U /* CPUID[D][1].ECX */
3131
#define FEAT_D_1_EDX 14U /* CPUID[D][1].EDX */
32-
#define FEATURE_WORDS 15U
32+
#define FEAT_7_2_EDX 15U /* CPUID[EAX=7,ECX=2].EDX */
33+
#define FEATURE_WORDS 16U
3334

3435
struct cpuinfo_x86 {
3536
/* SDM 2-2 Vol.4 Table 2-1 uses DisplayFamily_DisplayModel to

hypervisor/include/arch/x86/asm/cpufeatures.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@
9292
#define X86_FEATURE_CORE_CAP ((FEAT_7_0_EDX << 5U) + 30U)
9393
#define X86_FEATURE_SSBD ((FEAT_7_0_EDX << 5U) + 31U)
9494

95+
/* Intel-defined CPU features, CPUID level 0x00000007, sub 0x2 (EDX)*/
96+
#define X86_FEATURE_RRSBA_CTRL ((FEAT_7_2_EDX << 5U) + 2U)
97+
9598
/* Intel-defined CPU features, CPUID level 0x80000001 (EDX)*/
9699
#define X86_FEATURE_NX ((FEAT_8000_0001_EDX << 5U) + 20U)
97100
#define X86_FEATURE_PAGE1GB ((FEAT_8000_0001_EDX << 5U) + 26U)

hypervisor/include/arch/x86/asm/msr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu);
657657
/* SPEC & PRED bit */
658658
#define SPEC_ENABLE_IBRS (1U << 0U)
659659
#define SPEC_ENABLE_STIBP (1U << 1U)
660+
#define SPEC_RRSBA_DIS_S (1U << 6U)
660661
#define PRED_SET_IBPB (1U << 0U)
661662

662663
/* IA32 ARCH Capabilities bit */
@@ -667,6 +668,7 @@ void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu);
667668
#define IA32_ARCH_CAP_SSB_NO (1UL << 4U)
668669
#define IA32_ARCH_CAP_MDS_NO (1UL << 5U)
669670
#define IA32_ARCH_CAP_IF_PSCHANGE_MC_NO (1UL << 6U)
671+
#define IA32_ARCH_CAP_RESTRICTED_RSBA (1UL << 19U)
670672

671673
/* Flush L1 D-cache */
672674
#define IA32_L1D_FLUSH (1UL << 0U)

hypervisor/include/arch/x86/asm/security.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ bool check_cpu_security_cap(void);
2323
void cpu_internal_buffers_clear(void);
2424
bool is_ept_force_4k_ipage(void);
2525
uint64_t get_random_value(void);
26+
void disable_rrsba(void);
2627

2728
#ifdef STACK_PROTECTOR
2829
struct stack_canary {

0 commit comments

Comments
 (0)