| From 07708c4af1346ab1521b26a202f438366b7bcffd Mon Sep 17 00:00:00 2001 |
| From: Jan Kiszka <jan.kiszka@siemens.com> |
| Date: Mon, 3 Aug 2009 18:43:28 +0200 |
| Subject: KVM: x86: Disallow hypercalls for guest callers in rings > 0 |
| |
| From: Jan Kiszka <jan.kiszka@siemens.com> |
| |
| commit 07708c4af1346ab1521b26a202f438366b7bcffd upstream. |
| |
| So far unprivileged guest callers running in ring 3 can issue, e.g., MMU |
| hypercalls. Normally, such callers cannot provide any hand-crafted MMU |
| command structure as it has to be passed by its physical address, but |
| they can still crash the guest kernel by passing random addresses. |
| |
| To close the hole, this patch considers hypercalls valid only if issued |
| from guest ring 0. This may still be relaxed on a per-hypercall base in |
| the future once required. |
| |
| Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> |
| Signed-off-by: Avi Kivity <avi@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| arch/x86/kvm/x86.c | 6 ++++++ |
| include/linux/kvm_para.h | 1 + |
| 2 files changed, 7 insertions(+) |
| |
| --- a/arch/x86/kvm/x86.c |
| +++ b/arch/x86/kvm/x86.c |
| @@ -2911,6 +2911,11 @@ int kvm_emulate_hypercall(struct kvm_vcp |
| a3 &= 0xFFFFFFFF; |
| } |
| |
| + if (kvm_x86_ops->get_cpl(vcpu) != 0) { |
| + ret = -KVM_EPERM; |
| + goto out; |
| + } |
| + |
| switch (nr) { |
| case KVM_HC_VAPIC_POLL_IRQ: |
| ret = 0; |
| @@ -2922,6 +2927,7 @@ int kvm_emulate_hypercall(struct kvm_vcp |
| ret = -KVM_ENOSYS; |
| break; |
| } |
| +out: |
| kvm_register_write(vcpu, VCPU_REGS_RAX, ret); |
| ++vcpu->stat.hypercalls; |
| return r; |
| --- a/include/linux/kvm_para.h |
| +++ b/include/linux/kvm_para.h |
| @@ -13,6 +13,7 @@ |
| #define KVM_ENOSYS 1000 |
| #define KVM_EFAULT EFAULT |
| #define KVM_E2BIG E2BIG |
| +#define KVM_EPERM EPERM |
| |
| #define KVM_HC_VAPIC_POLL_IRQ 1 |
| #define KVM_HC_MMU_OP 2 |