Skip to content

Commit 37f66bb

Browse files
Maxim Levitskybonzini
Maxim Levitsky
authored andcommitted
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 <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 3ebb5d2 commit 37f66bb

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

arch/x86/kvm/emulate.c

+17-5
Original file line numberDiff line numberDiff line change
@@ -2505,9 +2505,14 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt,
25052505
*reg_write(ctxt, i) = GET_SMSTATE(u32, smstate, 0x7fd0 + i * 4);
25062506

25072507
val = GET_SMSTATE(u32, smstate, 0x7fcc);
2508-
ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1);
2508+
2509+
if (ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1))
2510+
return X86EMUL_UNHANDLEABLE;
2511+
25092512
val = GET_SMSTATE(u32, smstate, 0x7fc8);
2510-
ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1);
2513+
2514+
if (ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1))
2515+
return X86EMUL_UNHANDLEABLE;
25112516

25122517
selector = GET_SMSTATE(u32, smstate, 0x7fc4);
25132518
set_desc_base(&desc, GET_SMSTATE(u32, smstate, 0x7f64));
@@ -2560,16 +2565,23 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt,
25602565
ctxt->eflags = GET_SMSTATE(u32, smstate, 0x7f70) | X86_EFLAGS_FIXED;
25612566

25622567
val = GET_SMSTATE(u32, smstate, 0x7f68);
2563-
ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1);
2568+
2569+
if (ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1))
2570+
return X86EMUL_UNHANDLEABLE;
2571+
25642572
val = GET_SMSTATE(u32, smstate, 0x7f60);
2565-
ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1);
2573+
2574+
if (ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1))
2575+
return X86EMUL_UNHANDLEABLE;
25662576

25672577
cr0 = GET_SMSTATE(u64, smstate, 0x7f58);
25682578
cr3 = GET_SMSTATE(u64, smstate, 0x7f50);
25692579
cr4 = GET_SMSTATE(u64, smstate, 0x7f48);
25702580
ctxt->ops->set_smbase(ctxt, GET_SMSTATE(u32, smstate, 0x7f00));
25712581
val = GET_SMSTATE(u64, smstate, 0x7ed0);
2572-
ctxt->ops->set_msr(ctxt, MSR_EFER, val & ~EFER_LMA);
2582+
2583+
if (ctxt->ops->set_msr(ctxt, MSR_EFER, val & ~EFER_LMA))
2584+
return X86EMUL_UNHANDLEABLE;
25732585

25742586
selector = GET_SMSTATE(u32, smstate, 0x7e90);
25752587
rsm_set_desc_flags(&desc, GET_SMSTATE(u32, smstate, 0x7e92) << 8);

0 commit comments

Comments
 (0)