* [PATCH 1/3] KVM: x86/xen: Validate port number in SCHEDOP_poll
@ 2022-11-23 0:20 David Woodhouse
2022-11-23 0:20 ` [PATCH 2/3] KVM: x86/xen: Only do in-kernel acceleration of hypercalls for guest CPL0 David Woodhouse
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: David Woodhouse @ 2022-11-23 0:20 UTC (permalink / raw)
To: Paolo Bonzini, Sean Christopherson; +Cc: Michal Luczaj, kvm
From: David Woodhouse <dwmw@amazon.co.uk>
We shouldn't allow guests to poll on arbitrary port numbers off the end
of the event channel table.
Fixes: 1a65105a5aba ("KVM: x86/xen: handle PV spinlocks slowpath")
[dwmw2: my bug though; the original version did check the validity as a
side-effect of an idr_find() which I ripped out in refactoring.]
Reported-by: Michal Luczaj <mhal@rbox.co>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Cc: stable@kernel.org
---
arch/x86/kvm/xen.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
index 2dae413bd62a..dc2f304f2e69 100644
--- a/arch/x86/kvm/xen.c
+++ b/arch/x86/kvm/xen.c
@@ -954,6 +954,14 @@ static int kvm_xen_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
return kvm_xen_hypercall_set_result(vcpu, run->xen.u.hcall.result);
}
+static inline int max_evtchn_port(struct kvm *kvm)
+{
+ if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode)
+ return EVTCHN_2L_NR_CHANNELS;
+ else
+ return COMPAT_EVTCHN_2L_NR_CHANNELS;
+}
+
static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports,
evtchn_port_t *ports)
{
@@ -1042,6 +1050,10 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode,
*r = -EFAULT;
goto out;
}
+ if (ports[i] >= max_evtchn_port(vcpu->kvm)) {
+ *r = -EINVAL;
+ goto out;
+ }
}
if (sched_poll.nr_ports == 1)
@@ -1297,14 +1309,6 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
return 0;
}
-static inline int max_evtchn_port(struct kvm *kvm)
-{
- if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode)
- return EVTCHN_2L_NR_CHANNELS;
- else
- return COMPAT_EVTCHN_2L_NR_CHANNELS;
-}
-
static void kvm_xen_check_poller(struct kvm_vcpu *vcpu, int port)
{
int poll_evtchn = vcpu->arch.xen.poll_evtchn;
--
2.35.3
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 2/3] KVM: x86/xen: Only do in-kernel acceleration of hypercalls for guest CPL0 2022-11-23 0:20 [PATCH 1/3] KVM: x86/xen: Validate port number in SCHEDOP_poll David Woodhouse @ 2022-11-23 0:20 ` David Woodhouse 2022-11-23 16:26 ` Sean Christopherson 2022-11-23 0:20 ` [PATCH 3/3] KVM: Update gfn_to_pfn_cache khva when it moves within the same page David Woodhouse 2022-11-23 16:25 ` [PATCH 1/3] KVM: x86/xen: Validate port number in SCHEDOP_poll Sean Christopherson 2 siblings, 1 reply; 7+ messages in thread From: David Woodhouse @ 2022-11-23 0:20 UTC (permalink / raw) To: Paolo Bonzini, Sean Christopherson; +Cc: Michal Luczaj, kvm From: David Woodhouse <dwmw@amazon.co.uk> There are almost no hypercalls which are valid from CPL > 0, and definitely none which are handled by the kernel. Fixes: 2fd6df2f2b47 ("KVM: x86/xen: intercept EVTCHNOP_send from guests") Reported-by: Michal Luczaj <mhal@rbox.co> Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> Cc: stable@kernel.org --- arch/x86/kvm/xen.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index dc2f304f2e69..f3098c0e386a 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -1227,6 +1227,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) bool longmode; u64 input, params[6], r = -ENOSYS; bool handled = false; + u8 cpl; input = (u64)kvm_register_read(vcpu, VCPU_REGS_RAX); @@ -1254,9 +1255,17 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) params[5] = (u64)kvm_r9_read(vcpu); } #endif + cpl = static_call(kvm_x86_get_cpl)(vcpu); trace_kvm_xen_hypercall(input, params[0], params[1], params[2], params[3], params[4], params[5]); + /* + * Only allow hypercall acceleration for CPL0. The rare hypercalls that + * are permitted in guest userspace can be handled by the VMM. + */ + if (unlikely(cpl > 0)) + goto handle_in_userspace; + switch (input) { case __HYPERVISOR_xen_version: if (params[0] == XENVER_version && vcpu->kvm->arch.xen.xen_version) { @@ -1291,10 +1300,11 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) if (handled) return kvm_xen_hypercall_set_result(vcpu, r); +handle_in_userspace: vcpu->run->exit_reason = KVM_EXIT_XEN; vcpu->run->xen.type = KVM_EXIT_XEN_HCALL; vcpu->run->xen.u.hcall.longmode = longmode; - vcpu->run->xen.u.hcall.cpl = static_call(kvm_x86_get_cpl)(vcpu); + vcpu->run->xen.u.hcall.cpl = cpl; vcpu->run->xen.u.hcall.input = input; vcpu->run->xen.u.hcall.params[0] = params[0]; vcpu->run->xen.u.hcall.params[1] = params[1]; -- 2.35.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] KVM: x86/xen: Only do in-kernel acceleration of hypercalls for guest CPL0 2022-11-23 0:20 ` [PATCH 2/3] KVM: x86/xen: Only do in-kernel acceleration of hypercalls for guest CPL0 David Woodhouse @ 2022-11-23 16:26 ` Sean Christopherson 0 siblings, 0 replies; 7+ messages in thread From: Sean Christopherson @ 2022-11-23 16:26 UTC (permalink / raw) To: David Woodhouse; +Cc: Paolo Bonzini, Michal Luczaj, kvm On Wed, Nov 23, 2022, David Woodhouse wrote: > From: David Woodhouse <dwmw@amazon.co.uk> > > There are almost no hypercalls which are valid from CPL > 0, and definitely > none which are handled by the kernel. > > Fixes: 2fd6df2f2b47 ("KVM: x86/xen: intercept EVTCHNOP_send from guests") > Reported-by: Michal Luczaj <mhal@rbox.co> > Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> > Cc: stable@kernel.org > --- Reviewed-by: Sean Christopherson <seanjc@google.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/3] KVM: Update gfn_to_pfn_cache khva when it moves within the same page 2022-11-23 0:20 [PATCH 1/3] KVM: x86/xen: Validate port number in SCHEDOP_poll David Woodhouse 2022-11-23 0:20 ` [PATCH 2/3] KVM: x86/xen: Only do in-kernel acceleration of hypercalls for guest CPL0 David Woodhouse @ 2022-11-23 0:20 ` David Woodhouse 2022-11-23 12:25 ` David Woodhouse 2022-11-23 16:25 ` [PATCH 1/3] KVM: x86/xen: Validate port number in SCHEDOP_poll Sean Christopherson 2 siblings, 1 reply; 7+ messages in thread From: David Woodhouse @ 2022-11-23 0:20 UTC (permalink / raw) To: Paolo Bonzini, Sean Christopherson; +Cc: Michal Luczaj, kvm From: David Woodhouse <dwmw@amazon.co.uk> In the case where a GPC is refreshed to a different location within the same page, we didn't bother to update it. Mostly we don't need to, but since the ->khva field also includes the offset within the page, that does have to be updated. Fixes: 982ed0de4753 ("KVM: Reinstate gfn_to_pfn_cache with invalidation support") Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> Reviewed-by: Paul Durrant <paul@xen.org> Cc: stable@kernel.org --- virt/kvm/pfncache.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c index bd4a46aee384..5f83321bfd2a 100644 --- a/virt/kvm/pfncache.c +++ b/virt/kvm/pfncache.c @@ -297,7 +297,12 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, if (!gpc->valid || old_uhva != gpc->uhva) { ret = hva_to_pfn_retry(kvm, gpc); } else { - /* If the HVA→PFN mapping was already valid, don't unmap it. */ + /* + * If the HVA→PFN mapping was already valid, don't unmap it. + * But do update gpc->khva because the offset within the page + * may have changed. + */ + gpc->khva = old_khva + page_offset; old_pfn = KVM_PFN_ERR_FAULT; old_khva = NULL; ret = 0; -- 2.35.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] KVM: Update gfn_to_pfn_cache khva when it moves within the same page 2022-11-23 0:20 ` [PATCH 3/3] KVM: Update gfn_to_pfn_cache khva when it moves within the same page David Woodhouse @ 2022-11-23 12:25 ` David Woodhouse 2022-11-23 16:10 ` Sean Christopherson 0 siblings, 1 reply; 7+ messages in thread From: David Woodhouse @ 2022-11-23 12:25 UTC (permalink / raw) To: Paolo Bonzini, Sean Christopherson; +Cc: Michal Luczaj, kvm [-- Attachment #1: Type: text/plain, Size: 1897 bytes --] On Wed, 2022-11-23 at 00:20 +0000, David Woodhouse wrote: > From: David Woodhouse <dwmw@amazon.co.uk> > > In the case where a GPC is refreshed to a different location within the > same page, we didn't bother to update it. Mostly we don't need to, but > since the ->khva field also includes the offset within the page, that > does have to be updated. > > Fixes: 982ed0de4753 ("KVM: Reinstate gfn_to_pfn_cache with invalidation support") Hm, wait. That commit wasn't actually broken because at that point the page offset was included in the uhva too, so the uhva *did* change and we'd (gratuitously) take the slower path through hva_to_pfn_retry() when the GPA moved within the same page. So I think this should actually be: Fixes: 3ba2c95ea180 ("KVM: Do not incorporate page offset into gfn=>pfn cache user address") Which means it's only relevant back to v6.0 stable, not all the way back to v5.17. > Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> > Reviewed-by: Paul Durrant <paul@xen.org> > Cc: stable@kernel.org > > --- > virt/kvm/pfncache.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c > index bd4a46aee384..5f83321bfd2a 100644 > --- a/virt/kvm/pfncache.c > +++ b/virt/kvm/pfncache.c > @@ -297,7 +297,12 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, > if (!gpc->valid || old_uhva != gpc->uhva) { > ret = hva_to_pfn_retry(kvm, gpc); > } else { > - /* If the HVA→PFN mapping was already valid, don't unmap it. */ > + /* > + * If the HVA→PFN mapping was already valid, don't unmap it. > + * But do update gpc->khva because the offset within the page > + * may have changed. > + */ > + gpc->khva = old_khva + page_offset; > old_pfn = KVM_PFN_ERR_FAULT; > old_khva = NULL; > ret = 0; > [-- Attachment #2: smime.p7s --] [-- Type: application/pkcs7-signature, Size: 5965 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] KVM: Update gfn_to_pfn_cache khva when it moves within the same page 2022-11-23 12:25 ` David Woodhouse @ 2022-11-23 16:10 ` Sean Christopherson 0 siblings, 0 replies; 7+ messages in thread From: Sean Christopherson @ 2022-11-23 16:10 UTC (permalink / raw) To: David Woodhouse; +Cc: Paolo Bonzini, Michal Luczaj, kvm On Wed, Nov 23, 2022, David Woodhouse wrote: > On Wed, 2022-11-23 at 00:20 +0000, David Woodhouse wrote: > > From: David Woodhouse <dwmw@amazon.co.uk> > > > > In the case where a GPC is refreshed to a different location within the > > same page, we didn't bother to update it. Mostly we don't need to, but > > since the ->khva field also includes the offset within the page, that > > does have to be updated. > > > > Fixes: 982ed0de4753 ("KVM: Reinstate gfn_to_pfn_cache with invalidation support") > > Hm, wait. That commit wasn't actually broken because at that point the > page offset was included in the uhva too, so the uhva *did* change and > we'd (gratuitously) take the slower path through hva_to_pfn_retry() > when the GPA moved within the same page. > > So I think this should actually be: > > Fixes: 3ba2c95ea180 ("KVM: Do not incorporate page offset into gfn=>pfn cache user address") Ya. > Which means it's only relevant back to v6.0 stable, not all the way > back to v5.17. Probably a moot point in the long run since that commit was tagged for stable@ too, in order to simplify the fixes that followed. > > Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> > > Reviewed-by: Paul Durrant <paul@xen.org> > > Cc: stable@kernel.org > > > > --- Reviewed-by: Sean Christopherson <seanjc@google.com> > > virt/kvm/pfncache.c | 7 ++++++- > > 1 file changed, 6 insertions(+), 1 deletion(-) > > > > diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c > > index bd4a46aee384..5f83321bfd2a 100644 > > --- a/virt/kvm/pfncache.c > > +++ b/virt/kvm/pfncache.c > > @@ -297,7 +297,12 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, > > if (!gpc->valid || old_uhva != gpc->uhva) { > > ret = hva_to_pfn_retry(kvm, gpc); > > } else { > > - /* If the HVA→PFN mapping was already valid, don't unmap it. */ > > + /* > > + * If the HVA→PFN mapping was already valid, don't unmap it. > > + * But do update gpc->khva because the offset within the page > > + * may have changed. > > + */ > > + gpc->khva = old_khva + page_offset; If/when we rework the APIs, another possible approach would be to store only the the page aligned address, e.g. force the user to pass in offset+len by doing something like: r = kvm_gpc_lock(...); if (r) return r; my_struct = kvm_gpc_kmap(..., offset, len); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] KVM: x86/xen: Validate port number in SCHEDOP_poll 2022-11-23 0:20 [PATCH 1/3] KVM: x86/xen: Validate port number in SCHEDOP_poll David Woodhouse 2022-11-23 0:20 ` [PATCH 2/3] KVM: x86/xen: Only do in-kernel acceleration of hypercalls for guest CPL0 David Woodhouse 2022-11-23 0:20 ` [PATCH 3/3] KVM: Update gfn_to_pfn_cache khva when it moves within the same page David Woodhouse @ 2022-11-23 16:25 ` Sean Christopherson 2 siblings, 0 replies; 7+ messages in thread From: Sean Christopherson @ 2022-11-23 16:25 UTC (permalink / raw) To: David Woodhouse; +Cc: Paolo Bonzini, Michal Luczaj, kvm On Wed, Nov 23, 2022, David Woodhouse wrote: > From: David Woodhouse <dwmw@amazon.co.uk> > > We shouldn't allow guests to poll on arbitrary port numbers off the end > of the event channel table. > > Fixes: 1a65105a5aba ("KVM: x86/xen: handle PV spinlocks slowpath") > [dwmw2: my bug though; the original version did check the validity as a > side-effect of an idr_find() which I ripped out in refactoring.] > Reported-by: Michal Luczaj <mhal@rbox.co> > Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> > Cc: stable@kernel.org > --- Reviewed-by: Sean Christopherson <seanjc@google.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-11-23 16:26 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-11-23 0:20 [PATCH 1/3] KVM: x86/xen: Validate port number in SCHEDOP_poll David Woodhouse 2022-11-23 0:20 ` [PATCH 2/3] KVM: x86/xen: Only do in-kernel acceleration of hypercalls for guest CPL0 David Woodhouse 2022-11-23 16:26 ` Sean Christopherson 2022-11-23 0:20 ` [PATCH 3/3] KVM: Update gfn_to_pfn_cache khva when it moves within the same page David Woodhouse 2022-11-23 12:25 ` David Woodhouse 2022-11-23 16:10 ` Sean Christopherson 2022-11-23 16:25 ` [PATCH 1/3] KVM: x86/xen: Validate port number in SCHEDOP_poll Sean Christopherson
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.