KVM: x86: Inject #GP when loading system segments with non-canonical base
authorNadav Amit <namit@cs.technion.ac.il>
Sun, 2 Nov 2014 09:54:56 +0000 (11:54 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 7 Nov 2014 14:44:09 +0000 (15:44 +0100)
When emulating LTR/LDTR/LGDT/LIDT, #GP should be injected if the base is
non-canonical. Otherwise, VM-entry will fail.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/emulate.c

index c86b3781fca2f7293b93705c82ab11abfaf75394..fab270801809d1ca725c14f65c96359c07e644cd 100644 (file)
@@ -1620,6 +1620,9 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
                                sizeof(base3), &ctxt->exception);
                if (ret != X86EMUL_CONTINUE)
                        return ret;
+               if (is_noncanonical_address(get_desc_base(&seg_desc) |
+                                            ((u64)base3 << 32)))
+                       return emulate_gp(ctxt, 0);
        }
 load:
        ctxt->ops->set_segment(ctxt, selector, &seg_desc, base3, seg);
@@ -3339,6 +3342,9 @@ static int em_lgdt_lidt(struct x86_emulate_ctxt *ctxt, bool lgdt)
                             ctxt->op_bytes);
        if (rc != X86EMUL_CONTINUE)
                return rc;
+       if (ctxt->mode == X86EMUL_MODE_PROT64 &&
+           is_noncanonical_address(desc_ptr.address))
+               return emulate_gp(ctxt, 0);
        if (lgdt)
                ctxt->ops->set_gdt(ctxt, &desc_ptr);
        else