From: Norbert Manthey <nmanthey@amazon.de>
To: xen-devel@lists.xenproject.org
Cc: Juergen Gross <jgross@suse.com>, Tim Deegan <tim@xen.org>,
Stefano Stabellini <sstabellini@kernel.org>,
Wei Liu <wei.liu2@citrix.com>,
Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
George Dunlap <George.Dunlap@eu.citrix.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Ian Jackson <ian.jackson@eu.citrix.com>,
Dario Faggioli <dfaggioli@suse.com>,
Martin Pohlack <mpohlack@amazon.de>,
Pawel Wieczorkiewicz <wipawel@amazon.de>,
Julien Grall <julien.grall@arm.com>,
David Woodhouse <dwmw@amazon.co.uk>,
Jan Beulich <jbeulich@suse.com>,
Martin Mazein <amazein@amazon.de>,
Julian Stecklina <jsteckli@amazon.de>,
Bjoern Doebel <doebel@amazon.de>,
Norbert Manthey <nmanthey@amazon.de>
Subject: [PATCH SpectreV1+L1TF v7 1/9] xen/evtchn: block speculative out-of-bound accesses
Date: Thu, 21 Feb 2019 09:16:35 +0100 [thread overview]
Message-ID: <1550737003-25779-2-git-send-email-nmanthey@amazon.de> (raw)
In-Reply-To: <1550737003-25779-1-git-send-email-nmanthey@amazon.de>
Guests can issue event channel interaction with guest specified data.
To avoid speculative out-of-bound accesses, we use the nospec macros,
or the domain_vcpu function. Where appropriate, we use the vcpu_id of
the seleceted vcpu instead of the parameter that can be influenced by
the guest, so that only one access needs to be protected.
This is part of the speculative hardening effort.
Signed-off-by: Norbert Manthey <nmanthey@amazon.de>
---
Notes:
v7: mention speculative hardening in commit message
explain preferred use of internal data in commit message
drop update in set_global_virq_handler
xen/common/event_channel.c | 29 ++++++++++++++++++-----------
xen/common/event_fifo.c | 13 ++++++++++---
xen/include/xen/event.h | 5 +++--
3 files changed, 31 insertions(+), 16 deletions(-)
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -365,11 +365,16 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
return -EINVAL;
+ /*
+ * Make sure the guest controlled value virq is bounded even during
+ * speculative execution.
+ */
+ virq = array_index_nospec(virq, ARRAY_SIZE(v->virq_to_evtchn));
+
if ( virq_is_global(virq) && (vcpu != 0) )
return -EINVAL;
- if ( (vcpu < 0) || (vcpu >= d->max_vcpus) ||
- ((v = d->vcpu[vcpu]) == NULL) )
+ if ( (v = domain_vcpu(d, vcpu)) == NULL )
return -ENOENT;
spin_lock(&d->event_lock);
@@ -418,8 +423,7 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
int port, vcpu = bind->vcpu;
long rc = 0;
- if ( (vcpu < 0) || (vcpu >= d->max_vcpus) ||
- (d->vcpu[vcpu] == NULL) )
+ if ( domain_vcpu(d, vcpu) == NULL )
return -ENOENT;
spin_lock(&d->event_lock);
@@ -813,6 +817,7 @@ int set_global_virq_handler(struct domain *d, uint32_t virq)
if (virq >= NR_VIRQS)
return -EINVAL;
+
if (!virq_is_global(virq))
return -EINVAL;
@@ -930,8 +935,10 @@ long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id)
struct domain *d = current->domain;
struct evtchn *chn;
long rc = 0;
+ struct vcpu *v;
- if ( (vcpu_id >= d->max_vcpus) || (d->vcpu[vcpu_id] == NULL) )
+ /* Use the vcpu info to prevent speculative out-of-bound accesses */
+ if ( (v = domain_vcpu(d, vcpu_id)) == NULL )
return -ENOENT;
spin_lock(&d->event_lock);
@@ -955,22 +962,22 @@ long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id)
{
case ECS_VIRQ:
if ( virq_is_global(chn->u.virq) )
- chn->notify_vcpu_id = vcpu_id;
+ chn->notify_vcpu_id = v->vcpu_id;
else
rc = -EINVAL;
break;
case ECS_UNBOUND:
case ECS_INTERDOMAIN:
- chn->notify_vcpu_id = vcpu_id;
+ chn->notify_vcpu_id = v->vcpu_id;
break;
case ECS_PIRQ:
- if ( chn->notify_vcpu_id == vcpu_id )
+ if ( chn->notify_vcpu_id == v->vcpu_id )
break;
unlink_pirq_port(chn, d->vcpu[chn->notify_vcpu_id]);
- chn->notify_vcpu_id = vcpu_id;
+ chn->notify_vcpu_id = v->vcpu_id;
pirq_set_affinity(d, chn->u.pirq.irq,
- cpumask_of(d->vcpu[vcpu_id]->processor));
- link_pirq_port(port, chn, d->vcpu[vcpu_id]);
+ cpumask_of(v->processor));
+ link_pirq_port(port, chn, v);
break;
default:
rc = -EINVAL;
diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -33,7 +33,8 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
*/
smp_rmb();
- p = port / EVTCHN_FIFO_EVENT_WORDS_PER_PAGE;
+ p = array_index_nospec(port / EVTCHN_FIFO_EVENT_WORDS_PER_PAGE,
+ d->evtchn_fifo->num_evtchns);
w = port % EVTCHN_FIFO_EVENT_WORDS_PER_PAGE;
return d->evtchn_fifo->event_array[p] + w;
@@ -516,14 +517,20 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
gfn = init_control->control_gfn;
offset = init_control->offset;
- if ( vcpu_id >= d->max_vcpus || !d->vcpu[vcpu_id] )
+ if ( (v = domain_vcpu(d, vcpu_id)) == NULL )
return -ENOENT;
- v = d->vcpu[vcpu_id];
/* Must not cross page boundary. */
if ( offset > (PAGE_SIZE - sizeof(evtchn_fifo_control_block_t)) )
return -EINVAL;
+ /*
+ * Make sure the guest controlled value offset is bounded even during
+ * speculative execution.
+ */
+ offset = array_index_nospec(offset,
+ PAGE_SIZE - sizeof(evtchn_fifo_control_block_t) + 1);
+
/* Must be 8-bytes aligned. */
if ( offset & (8 - 1) )
return -EINVAL;
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -13,6 +13,7 @@
#include <xen/smp.h>
#include <xen/softirq.h>
#include <xen/bitops.h>
+#include <xen/nospec.h>
#include <asm/event.h>
/*
@@ -103,7 +104,7 @@ void arch_evtchn_inject(struct vcpu *v);
* The first bucket is directly accessed via d->evtchn.
*/
#define group_from_port(d, p) \
- ((d)->evtchn_group[(p) / EVTCHNS_PER_GROUP])
+ array_access_nospec((d)->evtchn_group, (p) / EVTCHNS_PER_GROUP)
#define bucket_from_port(d, p) \
((group_from_port(d, p))[((p) % EVTCHNS_PER_GROUP) / EVTCHNS_PER_BUCKET])
@@ -117,7 +118,7 @@ static inline bool_t port_is_valid(struct domain *d, unsigned int p)
static inline struct evtchn *evtchn_from_port(struct domain *d, unsigned int p)
{
if ( p < EVTCHNS_PER_BUCKET )
- return &d->evtchn[p];
+ return &d->evtchn[array_index_nospec(p, EVTCHNS_PER_BUCKET)];
return bucket_from_port(d, p) + (p % EVTCHNS_PER_BUCKET);
}
--
2.7.4
Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrer: Christian Schlaeger, Ralf Herbrich
Ust-ID: DE 289 237 879
Eingetragen am Amtsgericht Charlottenburg HRB 149173 B
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2019-02-21 8:18 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-21 8:16 SpectreV1+L1TF Patch Series v7 Norbert Manthey
2019-02-21 8:16 ` Norbert Manthey [this message]
2019-02-22 13:00 ` [PATCH SpectreV1+L1TF v7 1/9] xen/evtchn: block speculative out-of-bound accesses Jan Beulich
2019-02-25 12:45 ` Norbert Manthey
2019-02-21 8:16 ` [PATCH SpectreV1+L1TF v7 2/9] x86/vioapic: " Norbert Manthey
2019-02-22 13:02 ` Jan Beulich
2019-02-21 8:16 ` [PATCH SpectreV1+L1TF v7 3/9] spec: add l1tf-barrier Norbert Manthey
2019-02-22 13:13 ` Jan Beulich
2019-02-21 8:16 ` [PATCH SpectreV1+L1TF v7 4/9] nospec: introduce evaluate_nospec Norbert Manthey
2019-02-21 9:47 ` Julien Grall
2019-02-22 13:17 ` Jan Beulich
2019-02-25 8:18 ` Norbert Manthey
2019-02-21 8:16 ` [PATCH SpectreV1+L1TF v7 5/9] is_control_domain: block speculation Norbert Manthey
2019-02-22 13:19 ` Jan Beulich
2019-02-21 8:16 ` [PATCH SpectreV1+L1TF v7 6/9] is_hvm/pv_domain: " Norbert Manthey
2019-02-22 13:20 ` Jan Beulich
2019-02-21 8:16 ` [PATCH SpectreV1+L1TF v7 7/9] common/memory: block speculative out-of-bound accesses Norbert Manthey
2019-02-22 12:55 ` Jan Beulich
2019-02-21 8:16 ` [PATCH SpectreV1+L1TF v7 8/9] x86/hvm: add nospec to hvmop param Norbert Manthey
2019-02-22 14:39 ` Jan Beulich
2019-02-25 8:13 ` Norbert Manthey
2019-02-21 8:16 ` [PATCH SpectreV1+L1TF v7 9/9] common/grant_table: block speculative out-of-bound accesses Norbert Manthey
2019-02-22 15:08 ` Jan Beulich
2019-02-25 9:58 ` Norbert Manthey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1550737003-25779-2-git-send-email-nmanthey@amazon.de \
--to=nmanthey@amazon.de \
--cc=George.Dunlap@eu.citrix.com \
--cc=amazein@amazon.de \
--cc=andrew.cooper3@citrix.com \
--cc=dfaggioli@suse.com \
--cc=doebel@amazon.de \
--cc=dwmw@amazon.co.uk \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=jgross@suse.com \
--cc=jsteckli@amazon.de \
--cc=julien.grall@arm.com \
--cc=konrad.wilk@oracle.com \
--cc=mpohlack@amazon.de \
--cc=sstabellini@kernel.org \
--cc=tim@xen.org \
--cc=wei.liu2@citrix.com \
--cc=wipawel@amazon.de \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.