KVM: emulator: more strict rsm checks.
Don't ignore return values in rsm_load_state_64/32 to avoid loading invalid state from SMM state area if it was tampered with by the guest. This is primarly intended to avoid letting guest set bits in EFER (like EFER.SVME when nesting is disabled) by manipulating SMM save area. Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> Message-Id: <20200827171145.374620-8-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Родитель
3ebb5d2617
Коммит
37f66bbef0
|
@ -2505,9 +2505,14 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt,
|
|||
*reg_write(ctxt, i) = GET_SMSTATE(u32, smstate, 0x7fd0 + i * 4);
|
||||
|
||||
val = GET_SMSTATE(u32, smstate, 0x7fcc);
|
||||
ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1);
|
||||
|
||||
if (ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1))
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
|
||||
val = GET_SMSTATE(u32, smstate, 0x7fc8);
|
||||
ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1);
|
||||
|
||||
if (ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1))
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
|
||||
selector = GET_SMSTATE(u32, smstate, 0x7fc4);
|
||||
set_desc_base(&desc, GET_SMSTATE(u32, smstate, 0x7f64));
|
||||
|
@ -2560,16 +2565,23 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt,
|
|||
ctxt->eflags = GET_SMSTATE(u32, smstate, 0x7f70) | X86_EFLAGS_FIXED;
|
||||
|
||||
val = GET_SMSTATE(u32, smstate, 0x7f68);
|
||||
ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1);
|
||||
|
||||
if (ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1))
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
|
||||
val = GET_SMSTATE(u32, smstate, 0x7f60);
|
||||
ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1);
|
||||
|
||||
if (ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1))
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
|
||||
cr0 = GET_SMSTATE(u64, smstate, 0x7f58);
|
||||
cr3 = GET_SMSTATE(u64, smstate, 0x7f50);
|
||||
cr4 = GET_SMSTATE(u64, smstate, 0x7f48);
|
||||
ctxt->ops->set_smbase(ctxt, GET_SMSTATE(u32, smstate, 0x7f00));
|
||||
val = GET_SMSTATE(u64, smstate, 0x7ed0);
|
||||
ctxt->ops->set_msr(ctxt, MSR_EFER, val & ~EFER_LMA);
|
||||
|
||||
if (ctxt->ops->set_msr(ctxt, MSR_EFER, val & ~EFER_LMA))
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
|
||||
selector = GET_SMSTATE(u32, smstate, 0x7e90);
|
||||
rsm_set_desc_flags(&desc, GET_SMSTATE(u32, smstate, 0x7e92) << 8);
|
||||
|
|
Загрузка…
Ссылка в новой задаче