From 967baba2c6a3e4edb717cac01036072758c4fc28 Mon Sep 17 00:00:00 2001 From: Thijs Raymakers Date: Tue, 11 Nov 2025 19:35:09 +0800 Subject: [PATCH] KVM: x86: use array_index_nospec with indices that come from guest stable inclusion from stable-v6.6.104 commit f49161646e03d107ce81a99c6ca5da682fe5fb69 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ICYBRH Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=f49161646e03d107ce81a99c6ca5da682fe5fb69 -------------------------------- commit c87bd4dd43a624109c3cc42d843138378a7f4548 upstream. min and dest_id are guest-controlled indices. Using array_index_nospec() after the bounds checks clamps these values to mitigate speculative execution side-channels. Signed-off-by: Thijs Raymakers Cc: stable@vger.kernel.org Cc: Sean Christopherson Cc: Paolo Bonzini Cc: Greg Kroah-Hartman Fixes: 715062970f37 ("KVM: X86: Implement PV sched yield hypercall") Fixes: bdf7ffc89922 ("KVM: LAPIC: Fix pv ipis out-of-bounds access") Fixes: 4180bf1b655a ("KVM: X86: Implement "send IPI" hypercall") Link: https://lore.kernel.org/r/20250804064405.4802-1-thijs@raymakers.nl Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Signed-off-by: Wang Hai --- arch/x86/kvm/lapic.c | 2 ++ arch/x86/kvm/x86.c | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 66c7f2367bb3..c67610ae5e0b 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -836,6 +836,8 @@ static int __pv_send_ipi(unsigned long *ipi_bitmap, struct kvm_apic_map *map, if (min > map->max_apic_id) return 0; + min = array_index_nospec(min, map->max_apic_id + 1); + for_each_set_bit(i, ipi_bitmap, min((u32)BITS_PER_LONG, (map->max_apic_id - min + 1))) { if (map->phys_map[min + i]) { diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 7a98760a4c03..de851f3dff7b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9961,8 +9961,11 @@ static void kvm_sched_yield(struct kvm_vcpu *vcpu, unsigned long dest_id) rcu_read_lock(); map = rcu_dereference(vcpu->kvm->arch.apic_map); - if (likely(map) && dest_id <= map->max_apic_id && map->phys_map[dest_id]) - target = map->phys_map[dest_id]->vcpu; + if (likely(map) && dest_id <= map->max_apic_id) { + dest_id = array_index_nospec(dest_id, map->max_apic_id + 1); + if (map->phys_map[dest_id]) + target = map->phys_map[dest_id]->vcpu; + } rcu_read_unlock(); -- Gitee