Message ID | 1505731501-6821-1-git-send-email-yu.c.zhang@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 18.09.2017 12:45, Yu Zhang wrote: > Routine check_cr_write() will trigger emulator_get_cpuid()-> > kvm_cpuid() to get maxphyaddr, and NULL is passed as values > for ebx/ecx/edx. This is problematic because kvm_cpuid() will > dereference these pointers. > > Fixes: d1cd3ce90044 ("KVM: MMU: check guest CR3 reserved bits based on its physical address width.") > Reported-by: Jim Mattson <jmattson@google.com> > Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com> > --- > arch/x86/kvm/emulate.c | 8 +++++--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c > index 16bf665..15f527b 100644 > --- a/arch/x86/kvm/emulate.c > +++ b/arch/x86/kvm/emulate.c > @@ -4102,10 +4102,12 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt) > ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); > if (efer & EFER_LMA) { > u64 maxphyaddr; > - u32 eax = 0x80000008; > + u32 eax, ebx, ecx, edx; > > - if (ctxt->ops->get_cpuid(ctxt, &eax, NULL, NULL, > - NULL, false)) > + eax = 0x80000008; > + ecx = 0; > + if (ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, > + &edx, false)) > maxphyaddr = eax & 0xff; > else > maxphyaddr = 36; > Not sure if fixing kvm_cpuid() would be better. Reviewed-by: David Hildenbrand <david@redhat.com>
kvm_cpuid ultimately wants to write all four of the GPRs passed in by reference. I don't see any advantage to allowing some of these pointers to be NULL. Reviewed-by: Jim Mattson <jmattson@google.com> On Mon, Sep 18, 2017 at 5:19 AM, David Hildenbrand <david@redhat.com> wrote: > On 18.09.2017 12:45, Yu Zhang wrote: >> Routine check_cr_write() will trigger emulator_get_cpuid()-> >> kvm_cpuid() to get maxphyaddr, and NULL is passed as values >> for ebx/ecx/edx. This is problematic because kvm_cpuid() will >> dereference these pointers. >> >> Fixes: d1cd3ce90044 ("KVM: MMU: check guest CR3 reserved bits based on its physical address width.") >> Reported-by: Jim Mattson <jmattson@google.com> >> Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com> >> --- >> arch/x86/kvm/emulate.c | 8 +++++--- >> 1 file changed, 5 insertions(+), 3 deletions(-) >> >> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c >> index 16bf665..15f527b 100644 >> --- a/arch/x86/kvm/emulate.c >> +++ b/arch/x86/kvm/emulate.c >> @@ -4102,10 +4102,12 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt) >> ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); >> if (efer & EFER_LMA) { >> u64 maxphyaddr; >> - u32 eax = 0x80000008; >> + u32 eax, ebx, ecx, edx; >> >> - if (ctxt->ops->get_cpuid(ctxt, &eax, NULL, NULL, >> - NULL, false)) >> + eax = 0x80000008; >> + ecx = 0; >> + if (ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, >> + &edx, false)) >> maxphyaddr = eax & 0xff; >> else >> maxphyaddr = 36; >> > > Not sure if fixing kvm_cpuid() would be better. > > Reviewed-by: David Hildenbrand <david@redhat.com> > > -- > > Thanks, > > David
On 9/18/2017 11:56 PM, Jim Mattson wrote: > kvm_cpuid ultimately wants to write all four of the GPRs passed in by > reference. I don't see any advantage to allowing some of these > pointers to be NULL. Thanks for your comments, Jim & David. 2 reasons I did not choose to change kvm_cpuid(): 1> like Jim's comments, kvm_cpuid() will eventually write the *eax - *edx no matter a cpuid entry is found or not; 2> currently, return value of kvm_cpuid() is either true when an entry is found or false otherwise. We can change kvm_cpuid() to check the pointers of GPRs against NULL and return false immediately. Then the false value would have 2 different meanings - entry not found, or invalid params. Paolo, any suggestion? :-) Thanks Yu > Reviewed-by: Jim Mattson <jmattson@google.com> > > On Mon, Sep 18, 2017 at 5:19 AM, David Hildenbrand <david@redhat.com> wrote: >> On 18.09.2017 12:45, Yu Zhang wrote: >>> Routine check_cr_write() will trigger emulator_get_cpuid()-> >>> kvm_cpuid() to get maxphyaddr, and NULL is passed as values >>> for ebx/ecx/edx. This is problematic because kvm_cpuid() will >>> dereference these pointers. >>> >>> Fixes: d1cd3ce90044 ("KVM: MMU: check guest CR3 reserved bits based on its physical address width.") >>> Reported-by: Jim Mattson <jmattson@google.com> >>> Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com> >>> --- >>> arch/x86/kvm/emulate.c | 8 +++++--- >>> 1 file changed, 5 insertions(+), 3 deletions(-) >>> >>> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c >>> index 16bf665..15f527b 100644 >>> --- a/arch/x86/kvm/emulate.c >>> +++ b/arch/x86/kvm/emulate.c >>> @@ -4102,10 +4102,12 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt) >>> ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); >>> if (efer & EFER_LMA) { >>> u64 maxphyaddr; >>> - u32 eax = 0x80000008; >>> + u32 eax, ebx, ecx, edx; >>> >>> - if (ctxt->ops->get_cpuid(ctxt, &eax, NULL, NULL, >>> - NULL, false)) >>> + eax = 0x80000008; >>> + ecx = 0; >>> + if (ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, >>> + &edx, false)) >>> maxphyaddr = eax & 0xff; >>> else >>> maxphyaddr = 36; >>> >> Not sure if fixing kvm_cpuid() would be better. >> >> Reviewed-by: David Hildenbrand <david@redhat.com> >> >> -- >> >> Thanks, >> >> David
On 20/09/2017 08:35, Yu Zhang wrote: > > 2 reasons I did not choose to change kvm_cpuid(): 1> like Jim's > comments, kvm_cpuid() will eventually write the *eax - *edx no > matter a cpuid entry is found or not; 2> currently, return value of > kvm_cpuid() is either true when an entry is found or false otherwise. > We can change kvm_cpuid() to check the pointers of GPRs against NULL > and return false immediately. Then the false value would have 2 > different meanings - entry not found, or invalid params. > > Paolo, any suggestion? :-) Radim, has already sent this version to Linus. :) Paolo
On 9/20/2017 4:13 PM, Paolo Bonzini wrote: > On 20/09/2017 08:35, Yu Zhang wrote: >> 2 reasons I did not choose to change kvm_cpuid(): 1> like Jim's >> comments, kvm_cpuid() will eventually write the *eax - *edx no >> matter a cpuid entry is found or not; 2> currently, return value of >> kvm_cpuid() is either true when an entry is found or false otherwise. >> We can change kvm_cpuid() to check the pointers of GPRs against NULL >> and return false immediately. Then the false value would have 2 >> different meanings - entry not found, or invalid params. >> >> Paolo, any suggestion? :-) > Radim, has already sent this version to Linus. :) Got it. Thanks. :) Yu > Paolo >
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 16bf665..15f527b 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -4102,10 +4102,12 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt) ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); if (efer & EFER_LMA) { u64 maxphyaddr; - u32 eax = 0x80000008; + u32 eax, ebx, ecx, edx; - if (ctxt->ops->get_cpuid(ctxt, &eax, NULL, NULL, - NULL, false)) + eax = 0x80000008; + ecx = 0; + if (ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, + &edx, false)) maxphyaddr = eax & 0xff; else maxphyaddr = 36;
Routine check_cr_write() will trigger emulator_get_cpuid()-> kvm_cpuid() to get maxphyaddr, and NULL is passed as values for ebx/ecx/edx. This is problematic because kvm_cpuid() will dereference these pointers. Fixes: d1cd3ce90044 ("KVM: MMU: check guest CR3 reserved bits based on its physical address width.") Reported-by: Jim Mattson <jmattson@google.com> Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com> --- arch/x86/kvm/emulate.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)