mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Carlos López" <clopez@suse.de>
To: Sean Christopherson <seanjc@google.com>, Tony Luck <tony.luck@intel.com>
Cc: kvm@vger.kernel.org, pbonzini@redhat.com,
	Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
	Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	"maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)"
	<x86@kernel.org>, "H. Peter Anvin" <hpa@zytor.com>,
	Jue Wang <juew@google.com>,
	"open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)"
	<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] KVM: x86: Fix array_index_nospec() protection in kvm_vcpu_ioctl_x86_set_mce()
Date: Tue, 2 Jun 2026 21:56:20 +0200	[thread overview]
Message-ID: <b43be54c-329c-4b75-bd53-29ac63c1dd37@suse.de> (raw)
In-Reply-To: <agstY455kTIumJ5P@google.com>

On 5/18/26 5:16 PM, Sean Christopherson wrote:
> +Tony (questions regarding IA32_MCG_CTL and IA32_MCi_CTL behavior)
> 
> On Mon, May 18, 2026, Sean Christopherson wrote:
>> On Sat, May 16, 2026, Carlos López wrote:
>>> Commit aebc3ca19063 ("KVM: x86: Enable CMCI capability by default and
>>> handle injected UCNA errors") introduced kvm_vcpu_x86_set_ucna(), which
>>> accesses @vcpu->arch.mci_ctl2_banks[] using @mce->bank as the index. The
>>> @mce struct is user-controlled, provided via the KVM_X86_SET_MCE ioctl.
>>>
>>> The caller of this function, kvm_vcpu_ioctl_x86_set_mce(), bounds-checks
>>> @mce->bank and applies array_index_nospec() to advance the @banks
>>> pointer, but @mce->bank itself is passed through unclamped. On a
>>> speculative path that bypasses the bounds check, the raw @mce->bank
>>> value can index mci_ctl2_banks[] out-of-bounds.
>>>
>>> In practice this is a very weak gadget, and would at most allow leaking
>>> a single bit in a 64-bit integer, but prevent potential future issues by
>>> clamping @mce->bank in place with array_index_nospec(), before passing
>>> the struct to kvm_vcpu_x86_set_ucna().
>>>
>>> Fixes: aebc3ca19063 ("KVM: x86: Enable CMCI capability by default and handle injected UCNA errors")
>>> Signed-off-by: Carlos López <clopez@suse.de>
>>> ---
>>>  arch/x86/kvm/x86.c | 3 ++-
>>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
>>> index 209eae67ab18..2d2415031267 100644
>>> --- a/arch/x86/kvm/x86.c
>>> +++ b/arch/x86/kvm/x86.c
>>> @@ -5497,7 +5497,8 @@ static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu,
>>>  	if (mce->bank >= bank_num || !(mce->status & MCI_STATUS_VAL))
>>>  		return -EINVAL;
>>>  
>>> -	banks += array_index_nospec(4 * mce->bank, 4 * bank_num);
>>> +	mce->bank = array_index_nospec(mce->bank, bank_num);
>>> +	banks += 4 * mce->bank;
>>>  
>>>  	if (is_ucna(mce))
>>>  		return kvm_vcpu_x86_set_ucna(vcpu, mce, banks);
>>
>> As a follow-up, I think we should fold kvm_vcpu_x86_set_ucna() into
>> kvm_vcpu_ioctl_x86_set_mce().  Splitting it to a separately helper makes it
>> unnecessarily difficult to see the usage of mce->bank.
>>
>> Hmm, and isn't the handling of UNCA errors misplaced?  Per the SDM, the only
>> allowed values for IA32_MCG_CTL are -1ull and 0.
>>
>>   IA32_MCG_CTL controls the reporting of machine-check exceptions. If present,
>>   writing 1s to this register enables machine-check features and writing all 0s
>>   disables machine-check features. All other values are undefined and/or
>>   implementation specific.
>>
>> I don't see anything the SDM that exempts UNCA from that logic.  Ditto for the
>> similar IA32_MCi_CTL check.  So on top of your fix, over two patches, I think we
>> should end up with this?
> 
> ...
> 
>> Unless I'm wrong, I'll send a v2 with your fix plus two more patches.
> 
> Heh, I was partially wrong.  I think.  The IA32_MCi_CTL MSRs control whether or
> not a #MC is reported, but don't change error _logging_.
> 
>   Setting an EEj flag enables signaling #MC of the associated error and clearing
>   it disables signaling of the error. Error logging happens regardless of the
>   setting of these bits. The processor drops writes to bits that are not implemented.
> 
> Ah, I was definitely wrong.  Section 17.5 CORRECTED MACHINE CHECK ERROR INTERRUPT
> explicitly says so:
> 
>   CMCI is not affected by the CR4.MCE bit, and it is not affected by the
>   IA32_MCi_CTL MSRs.

Right, so the existing UCNA behavior is correct, since it always logs
the error and delivery is gated on MCi_CTL2.

> Actually, that means the existing code is wrong, and has been since commit
> 890ca9aefa78 ("KVM: Add MCE support").
>
> Hrm, and I'm not convinced KVM's handling of IA32_MCG_CTL is correct either.  The
> SDM says it controls reporting of _exceptions_, it doesn't say anything about
> disabling loggin of errors.
> 
>   IA32_MCG_CTL controls the reporting of machine-check exceptions.
> 
> 
> Tony,
> 
> Does clearing IA32_MCG_CTL affect error logging *and* #MC generation, or just #MC
> generation?  And if it impacts logging, does it also apply to UCNA errors?

The AMD manual does not clarify much either (9.3.1.3 Machine-Check
Global-Control Register):

  MCG_CTL is used by software to enable or disable the logging and
  reporting of machine-check errors from the implemented error-reporting
  banks. Depending on the implementation, detected errors from some
  error sources associated with a reporting bank that is disabled are
  still logged.

But my reading here is that MCG_CTL *does* control logging in the
general case, with some implementation-specific exceptions.

So if I get the picture correctly:

* UCNA error logging in KVM is always happens (good), and delivery is
  done via CMCI based on MCi_CTL2 (good). Nothing to fix here, unless
  MCG_CTL does affect logging (although it would be a bit strange for
  this to be true while CR4.MCE and MCi_CTL are explicitly mentioned to
  *not* have this behavior for CMCI).
* Non-UCNA error logging is broken, at least on the count that logging
  is gated based on MCi_CTL, when it should not. The spec is ambiguous
  on whether MCG_CTL controls logging for these. Current behavior in KVM
  is to *do* the gating based on MCG_CTL; the spec suggests that this
  may be correct at least on AMD (but it is not symmetric with MCi_CTL
  behavior).

  reply	other threads:[~2026-06-02 19:56 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-16 16:34 Carlos López
2026-05-18 14:46 ` Sean Christopherson
2026-05-18 15:16   ` Sean Christopherson
2026-06-02 19:56     ` Carlos López [this message]
2026-06-02 20:22       ` Carlos López

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b43be54c-329c-4b75-bd53-29ac63c1dd37@suse.de \
    --to=clopez@suse.de \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=juew@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=tglx@kernel.org \
    --cc=tony.luck@intel.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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®