[PATCH v3 2/2] kvm: x86: Disallow invalid exceptions from userspace

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Userspace should not be able to inject an invalid exception into a kvm
guest via KVM_SET_VCPU_EVENTS, nor should it be able to convert a
valid pending exception to an invalid one via KVM_SET_SREGS.

In particular, only certain exceptions deliver an error code in
protected mode, and no exception delivers an error code in
real-address mode.

Reported-by: syzbot <syzkaller@xxxxxxxxxxxxxxxx>
Signed-off-by: Jim Mattson <jmattson@xxxxxxxxxx>
Reviewed-by: Marc Orr <marcorr@xxxxxxxxxx>
---
 arch/x86/kvm/x86.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4ab569171ad1..b67a664b1d7b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3423,6 +3423,14 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 	    vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED)
 		return -EINVAL;
 
+	if (events->exception.injected) {
+		bool has_error_code = is_protmode(vcpu) &&
+			x86_exception_has_error_code(events->exception.nr);
+
+		if (!!events->exception.has_error_code != has_error_code)
+			return -EINVAL;
+	}
+
 	process_nmi(vcpu);
 	vcpu->arch.exception.injected = false;
 	vcpu->arch.exception.pending = events->exception.injected;
@@ -8170,6 +8178,14 @@ static int kvm_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 			return -EINVAL;
 	}
 
+	if (vcpu->arch.exception.injected || vcpu->arch.exception.pending) {
+		bool has_error_code = (sregs->cr0 & X86_CR0_PE) &&
+			x86_exception_has_error_code(vcpu->arch.exception.nr);
+
+		if (vcpu->arch.exception.has_error_code != has_error_code)
+			return -EINVAL;
+	}
+
 	return 0;
 }
 
-- 
2.19.1.331.ge82ca0e54c-goog




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux