KVM: VMX: Add array_index_nospec() to evmcs_field_offset()

evmcs_field_offset() bounds-checks the guest-supplied field index against
nr_evmcs_1_fields and then indexes vmcs_field_to_evmcs_1[] without an
array_index_nospec() clamp, unlike its vmcs12 counterpart
get_vmcs12_field_offset().

A regular VMREAD instruction is allowed while an enlightened VMCS is active
since 6cbbaab60f ("KVM: nVMX: Allow VMREAD when Enlightened VMCS is in
use"), and it reaches evmcs_field_offset() with a guest-supplied field
encoding. But because the index is not clamped, the guest may be able to
speculatively access past the bound check and read out of bounds of
vmcs_field_to_evmcs_1[] (Spectre v1). The leaked value is only the u16
'offset', so the exposure is limited.

The other callers of evmcs_field_offset() are not under direct guest
control, but the array_index_nospec() clamp does not hurt them.

Clamp the index with array_index_nospec(), mirroring
get_vmcs12_field_offset().

Fixes: 6cbbaab60f ("KVM: nVMX: Allow VMREAD when Enlightened VMCS is in use")
Signed-off-by: Amirmohammad Eftekhar <amirmohammad.eftekhar@cispa.de>
Message-ID: <20261031090529.65240-1-amirmohammad.eftekhar@cispa.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Amirmohammad Eftekhar 2026-10-31 10:05:29 +01:00 committed by Paolo Bonzini
parent 0cb8f16f88
commit d21eef2084

View File

@ -136,6 +136,8 @@ static __always_inline int evmcs_field_offset(unsigned long field,
if (unlikely(index >= nr_evmcs_1_fields))
return -ENOENT;
index = array_index_nospec(index, nr_evmcs_1_fields);
evmcs_field = &vmcs_field_to_evmcs_1[index];
/*