mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [BUG] KVM: nVMX: RSM re-entry reloads L2's DEBUGCTL/S_CET/SSP/SSP_TBL/BNDCFGS from vmcs01, not L2's pre-SMI values
@ 2026-10-17  9:30 Amirmohammad Eftekhar
  0 siblings, 0 replies; only message in thread
From: Amirmohammad Eftekhar @ 2026-10-17  9:30 UTC (permalink / raw)
  To: seanjc, pbonzini; +Cc: kvm, linux-kernel

Hi,

Reporting a nested-SMM fidelity bug (correctness, L1-self / L2-state; not
memory-safety and not guest->host). On RSM from SMM back into L2, KVM
re-stamps a set of guest MSR/state fields into vmcs02 from values it read out
of the *active* VMCS at the moment of re-entry -- which is still vmcs01 (L1's
live values) after the SMI forced the L2->L1 switch -- instead of L2's
pre-SMI values that were already saved into vmcs12.

The path
--------
vmx_leave_smm() -> nested_vmx_enter_non_root_mode(vcpu, from_vmentry=false)
runs with nested_run_pending == 0 (vmx_leave_smm() sets
KVM_NESTED_RUN_PENDING only *after* the re-entry call returns).

On that !from_vmentry re-entry, the "stash pre-VM-enter state" block reads the
current VMCS:

  vmx->nested.pre_vmenter_debugctl = vmx_guest_debugctl_read();     /* nested.c ~3677 */
  vmx->nested.pre_vmenter_bndcfgs  = vmcs_read64(GUEST_BNDCFGS);    /* ~3681 */
  vmcs_read_cet_state(vcpu, &vmx->nested.pre_vmenter_s_cet,         /* ~3685 */
                      &...ssp, &...ssp_tbl);

At this point the loaded VMCS is still vmcs01 (the SMI switched L2->L1 and RSM
has not switched back yet), so these reads capture L1's live DEBUGCTL / S_CET
/ SSP / SSP_TBL / BNDCFGS.

prepare_vmcs02()'s "no VM_ENTRY_LOAD_*" branch then stamps those stashed
values into vmcs02:

  vmx_guest_debugctl_write(vcpu, vmx->nested.pre_vmenter_debugctl);  /* nested.c ~2796 */
  vmcs_write_cet_state(vcpu, vmx->nested.pre_vmenter_s_cet,          /* ~2801 */
                       ssp, ssp_tbl);
  vmcs_write64(GUEST_BNDCFGS, vmx->nested.pre_vmenter_bndcfgs);      /* ~2807 */

But sync_vmcs02_to_vmcs12() already saved L2's correct values into vmcs12 when
the SMI was taken; RSM discards them and L2 resumes with L1's values for these
fields.

Impact / class
--------------
E2 fidelity. The victim is L2 and the entity that both owns L1 and drove the
SMI is L1, so this is L1-self-inflicted state corruption of its own L2, not a
privilege-boundary crossing, not guest->host, and not kvmCTF-scoring. It is a
concrete instance of the existing in-tree "L2's values may be corrupted on
SMI+RSM" TODO near vmx_enter_smm().

Suggested fix
-------------
On the !nested_run_pending (RSM) re-entry branch, source these fields from
vmcs12 (where sync_vmcs02_to_vmcs12 already put L2's values) rather than from
the active VMCS. Happy to send a patch once you confirm the preferred shape
(source-from-vmcs12 vs. reorder the vmcs switch so the stash reads vmcs02).

Read-confirmed against kvm-x86/next (tip of 2026-10-13) at the three anchors
above; the same pattern is present in mainline v7.3-rc6.

Thanks,
Amirmohammad

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-10-17  9:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-17  9:30 [BUG] KVM: nVMX: RSM re-entry reloads L2's DEBUGCTL/S_CET/SSP/SSP_TBL/BNDCFGS from vmcs01, not L2's pre-SMI values Amirmohammad Eftekhar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®