Skip to content

Commit 80eb5fe

Browse files
committed
Merge tag 'powerpc-spectre-rsb' of powerpc-CVE-2019-18660.bundle
Pull powerpc Spectre-RSB fixes from Michael Ellerman: "We failed to activate the mitigation for Spectre-RSB (Return Stack Buffer, aka. ret2spec) on context switch, on CPUs prior to Power9 DD2.3. That allows a process to poison the RSB (called Link Stack on Power CPUs) and possibly misdirect speculative execution of another process. If the victim process can be induced to execute a leak gadget then it may be possible to extract information from the victim via a side channel. The fix is to correctly activate the link stack flush mitigation on all CPUs that have any mitigation of Spectre v2 in userspace enabled. There's a second commit which adds a link stack flush in the KVM guest exit path. A leak via that path has not been demonstrated, but we believe it's at least theoretically possible. This is the fix for CVE-2019-18660" * tag 'powerpc-spectre-rsb' of /home/torvalds/Downloads/powerpc-CVE-2019-18660.bundle: KVM: PPC: Book3S HV: Flush link stack on guest exit to host kernel powerpc/book3s64: Fix link stack flush on context switch
2 parents 9a3d7fd + af2e8c6 commit 80eb5fe

File tree

5 files changed

+95
-4
lines changed

5 files changed

+95
-4
lines changed

arch/powerpc/include/asm/asm-prototypes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,12 @@ void _kvmppc_save_tm_pr(struct kvm_vcpu *vcpu, u64 guest_msr);
152152
/* Patch sites */
153153
extern s32 patch__call_flush_count_cache;
154154
extern s32 patch__flush_count_cache_return;
155+
extern s32 patch__flush_link_stack_return;
156+
extern s32 patch__call_kvm_flush_link_stack;
155157
extern s32 patch__memset_nocache, patch__memcpy_nocache;
156158

157159
extern long flush_count_cache;
160+
extern long kvm_flush_link_stack;
158161

159162
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
160163
void kvmppc_save_tm_hv(struct kvm_vcpu *vcpu, u64 msr, bool preserve_nv);

arch/powerpc/include/asm/security_features.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ static inline bool security_ftr_enabled(unsigned long feature)
8181
// Software required to flush count cache on context switch
8282
#define SEC_FTR_FLUSH_COUNT_CACHE 0x0000000000000400ull
8383

84+
// Software required to flush link stack on context switch
85+
#define SEC_FTR_FLUSH_LINK_STACK 0x0000000000001000ull
86+
8487

8588
// Features enabled by default
8689
#define SEC_FTR_DEFAULT \

arch/powerpc/kernel/entry_64.S

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ flush_count_cache:
537537
/* Save LR into r9 */
538538
mflr r9
539539

540+
// Flush the link stack
540541
.rept 64
541542
bl .+4
542543
.endr
@@ -546,6 +547,11 @@ flush_count_cache:
546547
.balign 32
547548
/* Restore LR */
548549
1: mtlr r9
550+
551+
// If we're just flushing the link stack, return here
552+
3: nop
553+
patch_site 3b patch__flush_link_stack_return
554+
549555
li r9,0x7fff
550556
mtctr r9
551557

arch/powerpc/kernel/security.c

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ enum count_cache_flush_type {
2424
COUNT_CACHE_FLUSH_HW = 0x4,
2525
};
2626
static enum count_cache_flush_type count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
27+
static bool link_stack_flush_enabled;
2728

2829
bool barrier_nospec_enabled;
2930
static bool no_nospec;
@@ -212,11 +213,19 @@ ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, c
212213

213214
if (ccd)
214215
seq_buf_printf(&s, "Indirect branch cache disabled");
216+
217+
if (link_stack_flush_enabled)
218+
seq_buf_printf(&s, ", Software link stack flush");
219+
215220
} else if (count_cache_flush_type != COUNT_CACHE_FLUSH_NONE) {
216221
seq_buf_printf(&s, "Mitigation: Software count cache flush");
217222

218223
if (count_cache_flush_type == COUNT_CACHE_FLUSH_HW)
219224
seq_buf_printf(&s, " (hardware accelerated)");
225+
226+
if (link_stack_flush_enabled)
227+
seq_buf_printf(&s, ", Software link stack flush");
228+
220229
} else if (btb_flush_enabled) {
221230
seq_buf_printf(&s, "Mitigation: Branch predictor state flush");
222231
} else {
@@ -377,18 +386,49 @@ static __init int stf_barrier_debugfs_init(void)
377386
device_initcall(stf_barrier_debugfs_init);
378387
#endif /* CONFIG_DEBUG_FS */
379388

389+
static void no_count_cache_flush(void)
390+
{
391+
count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
392+
pr_info("count-cache-flush: software flush disabled.\n");
393+
}
394+
380395
static void toggle_count_cache_flush(bool enable)
381396
{
382-
if (!enable || !security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) {
397+
if (!security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE) &&
398+
!security_ftr_enabled(SEC_FTR_FLUSH_LINK_STACK))
399+
enable = false;
400+
401+
if (!enable) {
383402
patch_instruction_site(&patch__call_flush_count_cache, PPC_INST_NOP);
384-
count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
385-
pr_info("count-cache-flush: software flush disabled.\n");
403+
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
404+
patch_instruction_site(&patch__call_kvm_flush_link_stack, PPC_INST_NOP);
405+
#endif
406+
pr_info("link-stack-flush: software flush disabled.\n");
407+
link_stack_flush_enabled = false;
408+
no_count_cache_flush();
386409
return;
387410
}
388411

412+
// This enables the branch from _switch to flush_count_cache
389413
patch_branch_site(&patch__call_flush_count_cache,
390414
(u64)&flush_count_cache, BRANCH_SET_LINK);
391415

416+
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
417+
// This enables the branch from guest_exit_cont to kvm_flush_link_stack
418+
patch_branch_site(&patch__call_kvm_flush_link_stack,
419+
(u64)&kvm_flush_link_stack, BRANCH_SET_LINK);
420+
#endif
421+
422+
pr_info("link-stack-flush: software flush enabled.\n");
423+
link_stack_flush_enabled = true;
424+
425+
// If we just need to flush the link stack, patch an early return
426+
if (!security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) {
427+
patch_instruction_site(&patch__flush_link_stack_return, PPC_INST_BLR);
428+
no_count_cache_flush();
429+
return;
430+
}
431+
392432
if (!security_ftr_enabled(SEC_FTR_BCCTR_FLUSH_ASSIST)) {
393433
count_cache_flush_type = COUNT_CACHE_FLUSH_SW;
394434
pr_info("count-cache-flush: full software flush sequence enabled.\n");
@@ -407,11 +447,20 @@ void setup_count_cache_flush(void)
407447
if (no_spectrev2 || cpu_mitigations_off()) {
408448
if (security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED) ||
409449
security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED))
410-
pr_warn("Spectre v2 mitigations not under software control, can't disable\n");
450+
pr_warn("Spectre v2 mitigations not fully under software control, can't disable\n");
411451

412452
enable = false;
413453
}
414454

455+
/*
456+
* There's no firmware feature flag/hypervisor bit to tell us we need to
457+
* flush the link stack on context switch. So we set it here if we see
458+
* either of the Spectre v2 mitigations that aim to protect userspace.
459+
*/
460+
if (security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED) ||
461+
security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE))
462+
security_ftr_set(SEC_FTR_FLUSH_LINK_STACK);
463+
415464
toggle_count_cache_flush(enable);
416465
}
417466

arch/powerpc/kvm/book3s_hv_rmhandlers.S

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*/
1212

1313
#include <asm/ppc_asm.h>
14+
#include <asm/code-patching-asm.h>
1415
#include <asm/kvm_asm.h>
1516
#include <asm/reg.h>
1617
#include <asm/mmu.h>
@@ -1487,6 +1488,13 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
14871488
1:
14881489
#endif /* CONFIG_KVM_XICS */
14891490

1491+
/*
1492+
* Possibly flush the link stack here, before we do a blr in
1493+
* guest_exit_short_path.
1494+
*/
1495+
1: nop
1496+
patch_site 1b patch__call_kvm_flush_link_stack
1497+
14901498
/* If we came in through the P9 short path, go back out to C now */
14911499
lwz r0, STACK_SLOT_SHORT_PATH(r1)
14921500
cmpwi r0, 0
@@ -1963,6 +1971,28 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
19631971
mtlr r0
19641972
blr
19651973

1974+
.balign 32
1975+
.global kvm_flush_link_stack
1976+
kvm_flush_link_stack:
1977+
/* Save LR into r0 */
1978+
mflr r0
1979+
1980+
/* Flush the link stack. On Power8 it's up to 32 entries in size. */
1981+
.rept 32
1982+
bl .+4
1983+
.endr
1984+
1985+
/* And on Power9 it's up to 64. */
1986+
BEGIN_FTR_SECTION
1987+
.rept 32
1988+
bl .+4
1989+
.endr
1990+
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
1991+
1992+
/* Restore LR */
1993+
mtlr r0
1994+
blr
1995+
19661996
kvmppc_guest_external:
19671997
/* External interrupt, first check for host_ipi. If this is
19681998
* set, we know the host wants us out so let's do it now

0 commit comments

Comments
 (0)