lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:   Wed, 25 Nov 2020 21:33:20 +0000
From:   Sean Christopherson <seanjc@...gle.com>
To:     彭浩(Richard) <richard.peng@...o.com>
Cc:     Paolo Bonzini <pbonzini@...hat.com>,
        "Suravee.Suthikulpanit@....com" <Suravee.Suthikulpanit@....com>,
        kvm@...r.kernel.org; <kvm@...r.kernel.org>,
        "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH] kvm/svm: fixed a potential register value inconsistent
 with variable ldr_reg

On Wed, Nov 25, 2020, 彭浩(Richard) wrote:
> If the ldr value is read out to zero, it does not call avic_ldr_write to update
> the virtual register, but the variable ldr_reg is updated.

Is there a failure associated with this?  And/or can you elaborate on why
skipping the svm->ldr_reg is correct?

I'm not familiar with the AVIC spec, and it's not at all clear to me what the
correct behavior should be for the LDR updates.  E.g. skipping the svm->ldr_reg
update appears to break avic_handle_apic_id_update(), which will see a stale
svm->ldr_reg and call avic_invalidate_logical_id_entry() when it presumably
should not.

> Fixes: 98d90582be2e ("SVM: Fix AVIC DFR and LDR handling")
> Signed-off-by: Peng Hao <richard.peng@...o.com>
> ---
>  arch/x86/kvm/svm/avic.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index 8c550999ace0..318735e0f2d0 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -417,7 +417,6 @@ static void avic_invalidate_logical_id_entry(struct kvm_vcpu *vcpu)
> 
>  static int avic_handle_ldr_update(struct kvm_vcpu *vcpu)
>  {
> -       int ret = 0;
>         struct vcpu_svm *svm = to_svm(vcpu);
>         u32 ldr = kvm_lapic_get_reg(vcpu->arch.apic, APIC_LDR);
>         u32 id = kvm_xapic_id(vcpu->arch.apic);
> @@ -427,13 +426,16 @@ static int avic_handle_ldr_update(struct kvm_vcpu *vcpu)
> 
>         avic_invalidate_logical_id_entry(vcpu);
> 
> -       if (ldr)
> +       if (ldr) {
> +               int ret;
>                 ret = avic_ldr_write(vcpu, id, ldr);
> 
> -       if (!ret)
> -               svm->ldr_reg = ldr;
> -
> -       return ret;
> +               if (!ret)
> +                       svm->ldr_reg = ldr;
> +               else
> +                       return ret;
> +       }
> +       return 0;
> }
> 
>  static int avic_handle_apic_id_update(struct kvm_vcpu *vcpu)
> --
> 2.18.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ