mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 12:03:54 +02:00
KVM: SEV: Use READ_ONCE() when reading entries/indices from PSC buffer
Use READ_ONCE() when reading entries/indices from the guest-accessible
Page State Change buffer to defend against TOCTOU bugs.
Don't bother with READ_ONCE()/WRITE_ONCE() for cases where KVM is writing
(and not consuming the result!), as the guest isn't supposed to touch the
buffer while it's being processed. I.e. using READ_ONCE() is all about
protecting against misbehaving guests.
Fixes: 9b54e248d2 ("KVM: SEV: Add support to handle Page State Change VMGEXIT")
Cc: stable@vger.kernel.org
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20260501202250.2115252-11-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
121d88de56
commit
c8cc238093
|
|
@ -3872,9 +3872,9 @@ static void __snp_complete_one_psc(struct vcpu_svm *svm)
|
|||
*/
|
||||
for (idx = svm->sev_es.psc_idx; svm->sev_es.psc_inflight;
|
||||
svm->sev_es.psc_inflight--, idx++) {
|
||||
struct psc_entry *entry = &entries[idx];
|
||||
struct psc_entry entry = READ_ONCE(entries[idx]);
|
||||
|
||||
entry->cur_page = entry->pagesize ? 512 : 1;
|
||||
entries[idx].cur_page = entry.pagesize ? 512 : 1;
|
||||
}
|
||||
|
||||
hdr->cur_entry = idx;
|
||||
|
|
@ -3938,8 +3938,8 @@ static int snp_begin_psc(struct vcpu_svm *svm)
|
|||
* validation, so take care to only use validated copies of values used
|
||||
* for things like array indexing.
|
||||
*/
|
||||
idx_start = hdr->cur_entry;
|
||||
idx_end = hdr->end_entry;
|
||||
idx_start = READ_ONCE(hdr->cur_entry);
|
||||
idx_end = READ_ONCE(hdr->end_entry);
|
||||
|
||||
if (idx_end >= max_nr_entries) {
|
||||
snp_complete_psc(svm, VMGEXIT_PSC_ERROR_INVALID_HDR);
|
||||
|
|
@ -3948,7 +3948,7 @@ static int snp_begin_psc(struct vcpu_svm *svm)
|
|||
|
||||
/* Find the start of the next range which needs processing. */
|
||||
for (idx = idx_start; idx <= idx_end; idx++, hdr->cur_entry++) {
|
||||
entry_start = entries[idx];
|
||||
entry_start = READ_ONCE(entries[idx]);
|
||||
|
||||
gfn = entry_start.gfn;
|
||||
huge = entry_start.pagesize;
|
||||
|
|
@ -3992,7 +3992,7 @@ static int snp_begin_psc(struct vcpu_svm *svm)
|
|||
* KVM_HC_MAP_GPA_RANGE exit.
|
||||
*/
|
||||
while (++idx <= idx_end) {
|
||||
struct psc_entry entry = entries[idx];
|
||||
struct psc_entry entry = READ_ONCE(entries[idx]);
|
||||
|
||||
if (entry.operation != entry_start.operation ||
|
||||
entry.gfn != entry_start.gfn + npages ||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user